Conversation
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. Walkthrough将 packages/taro-h5 包的测试框架从 Jest 迁移至 Vitest:新增 Vitest 配置并移除 Jest 配置,批量更新测试文件将 Jest API 替换为 Vitest(vi),调整 package.json 测试脚本与 devDependencies,新增/修改若干 package.json exports 与 mocks,测试用例异步风格从 done 回调迁移为 Promise/async/await。 Changes
Estimated code review effort🎯 3 (中等) | ⏱️ ~25 分钟
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
This PR migrates the taro-h5 package test suite from Jest to Vitest, aligning with the broader migration effort across the Taro repository.
Key Changes:
- Replaced Jest with Vitest as the test runner
- Migrated test configuration from
jest.config.tstovitest.config.mts - Updated test utilities from Jest APIs (
jest.fn,jest.spyOn) to Vitest APIs (vi.fn,vi.spyOn) - Converted most async tests from callback-based (
done) to Promise-based patterns - Updated package.json test scripts and dependencies
- Updated
@testing-library/jest-domto v6.6.3 for Vitest compatibility
Reviewed changes
Copilot reviewed 17 out of 18 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
packages/taro-h5/package.json |
Updated test scripts to use Vitest commands; removed Jest-specific dependencies (babel-jest, jest-fetch-mock, jest-mock-console, jest-transform-css, @types/testing-library__jest-dom); updated @testing-library/jest-dom to v6.6.3; added jsdom as explicit dependency |
packages/taro-h5/vitest.config.mts |
New Vitest configuration with jsdom environment, test file patterns, module aliases, and Istanbul coverage provider |
packages/taro-h5/jest.config.ts |
Removed Jest configuration file (no longer needed) |
packages/taro-h5/__mocks__/setEnv.ts |
Added import for @testing-library/jest-dom to setup file |
packages/taro-h5/__tests__/**/*.test.ts(x) |
Updated test files with Vitest APIs (vi.fn, vi.spyOn, vi.resetAllMocks), manual console mocking, Promise-based async patterns, and updated expect matchers for style assertions |
pnpm-lock.yaml |
Updated dependency resolution for the migration including Node.js type definitions changes (@types/node 20.19.9 -> 18.19.86 in some places) and removal of Jest-related packages |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (4)
packages/taro-h5/tests/ui/interaction/modal.test.ts:221
- This test still uses the
donecallback pattern which should be converted to a Promise-based approach for consistency with the other migrated tests in this file.
Convert to:
test('should res.cancel be true', () => {
return new Promise<void>(resolve => {
// ... existing code ...
done() // replace with resolve()
})
}) test('should res.cancel be true', done => {
const success = vi.fn()
const complete = vi.fn()
Taro.showModal({
success,
complete
})
.then(res => {
const errObj = {
errMsg: 'showModal:ok',
cancel: true,
confirm: false
}
expect(success).toHaveBeenCalledWith(errObj)
expect(complete).toHaveBeenCalledWith(errObj)
expect(res).toEqual(errObj)
done()
})
const modal: any = document.body.lastChild
const foot = modal.lastChild.lastChild
const cancel = foot.firstChild
setTimeout(() => {
cancel.click()
}, 200)
})
packages/taro-h5/tests/ui/interaction/loading.test.ts:81
- These tests still use the
donecallback pattern which should be converted to a Promise-based approach for consistency with the migration to Vitest.
Convert all three tests to use Promises:
test('basic test', () => {
return new Promise<void>(resolve => {
// ... existing code ...
setTimeout(() => {
expect(toast).toBeVisible()
expect(mask).not.toBeVisible()
resolve()
}, 200)
})
}) test('basic test', done => {
const titleContent = 'xxx'
const success = vi.fn()
const complete = vi.fn()
const errObj = { errMsg: 'showLoading:ok' }
Taro.showLoading({
title: titleContent,
success,
complete
})
.then(res => {
expect(res).toEqual(errObj)
})
const toast: any = document.body.lastChild
expect(toast.childNodes.length).toBe(2)
expect(toast).not.toBeVisible()
const mask = toast.firstChild
const icon: any = toast.lastChild.firstChild
const title = toast.lastChild.lastChild
expect(icon.style.animation).toMatch('taroLoading 1s steps(12, end) infinite')
expect(title).toHaveTextContent(titleContent)
expect(success).toHaveBeenCalledWith(errObj)
expect(complete).toHaveBeenCalledWith(errObj)
setTimeout(() => {
expect(toast).toBeVisible()
expect(mask).not.toBeVisible()
done()
}, 200)
})
test('should show mask', done => {
Taro.showLoading({
title: 'hello',
mask: true
})
const toast: any = document.body.lastChild
const mask = toast.firstChild
setTimeout(() => {
expect(mask).toBeVisible()
done()
}, 200)
})
test('should hide loading immediately', done => {
Taro.showLoading()
Taro.hideLoading()
const toast = document.body.lastChild
setTimeout(() => {
expect(toast).not.toBeVisible()
done()
}, 500)
})
packages/taro-h5/tests/ui/interaction/actionSheet.test.ts:177
- These tests still use the
donecallback pattern which should be converted to a Promise-based approach for consistency with the migration to Vitest.
Convert all three tests to use Promises with the pattern:
test('basic test', () => {
return new Promise<void>(resolve => {
// ... existing code ...
done() // replace with resolve()
})
}) test('basic test', done => {
const itemA = 'A'
const itemB = 'B'
const itemC = 'C'
const success = vi.fn()
const fail = vi.fn()
const complete = vi.fn()
Taro.showActionSheet({
itemList: [itemA, itemB, itemC],
success,
fail,
complete
})
.then(res => {
const expectObj = { errMsg: 'showActionSheet:ok', tapIndex: 0 }
expect(success).toHaveBeenCalledWith(expectObj)
expect(fail.mock.calls.length).toBe(0)
expect(complete).toHaveBeenCalledWith(expectObj)
expect(res).toEqual(expectObj)
done()
})
const actionSheet: any = document.body.lastChild
expect(actionSheet.childNodes.length).toBe(2)
const mask = actionSheet.firstChild
const list = actionSheet.lastChild.firstChild
expect(list.childNodes.length).toBe(4)
expect(list.childNodes[1]).toHaveTextContent(itemA)
expect(list.childNodes[2]).toHaveTextContent(itemB)
expect(list.childNodes[3]).toHaveTextContent(itemC)
setTimeout(() => {
expect(actionSheet).toBeVisible()
expect(mask).toBeVisible()
list.childNodes[1].click()
}, 200)
})
test('should hide actionSheet when cancel was clicked', done => {
const success = vi.fn()
const fail = vi.fn()
const complete = vi.fn()
Taro.showActionSheet({
itemList: ['A', 'B', 'C'],
success,
fail,
complete
})
const actionSheet: any = document.body.lastChild
const cancel = actionSheet.lastChild.lastChild
cancel.click()
setTimeout(() => {
const expectObj = { errMsg: 'showActionSheet:fail cancel' }
expect(actionSheet).not.toBeVisible()
expect(success.mock.calls.length).toBe(0)
expect(fail).toHaveBeenCalledWith(expectObj)
expect(complete).toHaveBeenCalledWith(expectObj)
done()
}, 200)
})
test('should hide actionSheet when mask was clicked', done => {
const success = vi.fn()
const fail = vi.fn()
const complete = vi.fn()
Taro.showActionSheet({
itemList: ['A', 'B', 'C'],
success,
fail,
complete
})
const actionSheet: any = document.body.lastChild
const mask = actionSheet.firstChild
mask.click()
setTimeout(() => {
const expectObj = { errMsg: 'showActionSheet:fail cancel' }
expect(actionSheet).not.toBeVisible()
expect(success.mock.calls.length).toBe(0)
expect(fail).toHaveBeenCalledWith(expectObj)
expect(complete).toHaveBeenCalledWith(expectObj)
done()
}, 200)
packages/taro-h5/tests/ui/interaction/modal.test.ts:165
- This test still uses the
donecallback pattern which should be converted to a Promise-based approach for consistency with the other migrated tests in this file.
Convert to:
test('basic test', () => {
return new Promise<void>(resolve => {
const titleContent = 'xxx'
const success = vi.fn()
const complete = vi.fn()
// ... existing code ...
done() // replace with resolve()
})
}) test('basic test', done => {
const titleText = 'xxx'
const contentText = 'hello world'
const cancelText = '取消'
const confirmText = '确定'
const success = vi.fn()
const complete = vi.fn()
Taro.showModal({
title: titleText,
content: contentText,
success,
complete
})
.then(res => {
const errObj = {
errMsg: 'showModal:ok',
cancel: false,
confirm: true
}
expect(success).toHaveBeenCalledWith(errObj)
expect(complete).toHaveBeenCalledWith(errObj)
expect(res).toEqual(errObj)
done()
})
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (4)
packages/taro-h5/__tests__/ui/tab-bar.test.tsx (1)
26-28: 注释掉的 DOM 断言可考虑移除或恢复。多处 DOM 断言被注释掉了。如果这些断言在 Vitest 环境下无法正常工作,建议添加 TODO 注释说明原因;如果是冗余的,建议直接删除以保持代码整洁。
Also applies to: 34-35, 51-52, 58-59, 73-74, 78-79
packages/taro-h5/__tests__/ui/interaction/actionSheet.test.ts (1)
91-111: 建议将done回调模式统一为 async/await。此文件中部分测试仍使用
done回调模式,而其他已迁移的测试文件使用async/await或Promise模式。为保持一致性,建议统一使用 async/await 模式。- test('basic test', done => { + test('basic test', async () => { const itemA = 'A' const itemB = 'B' const itemC = 'C' const success = vi.fn() const fail = vi.fn() const complete = vi.fn() - Taro.showActionSheet({ + const promise = Taro.showActionSheet({ itemList: [itemA, itemB, itemC], success, fail, complete }) - .then(res => { - const expectObj = { errMsg: 'showActionSheet:ok', tapIndex: 0 } - expect(success).toHaveBeenCalledWith(expectObj) - expect(fail.mock.calls.length).toBe(0) - expect(complete).toHaveBeenCalledWith(expectObj) - expect(res).toEqual(expectObj) - done() - }) // ... click handling ... + await vi.waitFor(async () => { + list.childNodes[1].click() + }) + const res = await promise + const expectObj = { errMsg: 'showActionSheet:ok', tapIndex: 0 } + expect(success).toHaveBeenCalledWith(expectObj) + expect(res).toEqual(expectObj)packages/taro-h5/__tests__/network/request.test.ts (1)
14-14: 考虑使用 Headers 对象替代 Map。
headers: new Map()可能与实际fetch响应的Headers对象行为不完全一致。如果测试需要验证 header 相关逻辑,建议使用new Headers()。- headers: new Map() + headers: new Headers()packages/taro-h5/__tests__/network/websocket.test.ts (1)
139-142: 调试日志可考虑移除。Lines 139-142 的
console.log调用看起来是调试用途,建议在合并前移除。- // eslint-disable-next-line no-console - console.log('Task:', task) - // eslint-disable-next-line no-console - console.log('Task WS:', task?.ws)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (17)
packages/taro-h5/__mocks__/setEnv.ts(1 hunks)packages/taro-h5/__tests__/base/network.test.ts(2 hunks)packages/taro-h5/__tests__/base/system.test.ts(2 hunks)packages/taro-h5/__tests__/location/index.test.ts(4 hunks)packages/taro-h5/__tests__/network/request.test.ts(7 hunks)packages/taro-h5/__tests__/network/websocket.test.ts(5 hunks)packages/taro-h5/__tests__/storage/index.test.ts(9 hunks)packages/taro-h5/__tests__/ui/interaction/actionSheet.test.ts(9 hunks)packages/taro-h5/__tests__/ui/interaction/loading.test.ts(2 hunks)packages/taro-h5/__tests__/ui/interaction/modal.test.ts(11 hunks)packages/taro-h5/__tests__/ui/interaction/toast.test.ts(3 hunks)packages/taro-h5/__tests__/ui/navigation.test.ts(4 hunks)packages/taro-h5/__tests__/ui/tab-bar.test.tsx(4 hunks)packages/taro-h5/__tests__/wxml/index.test.ts(3 hunks)packages/taro-h5/jest.config.ts(0 hunks)packages/taro-h5/package.json(2 hunks)packages/taro-h5/vitest.config.mts(1 hunks)
💤 Files with no reviewable changes (1)
- packages/taro-h5/jest.config.ts
🧰 Additional context used
🧠 Learnings (9)
📓 Common learnings
Learnt from: ianzone
Repo: NervJS/taro PR: 18146
File: packages/babel-plugin-transform-react-jsx-to-rn-stylesheet/package.json:12-14
Timestamp: 2025-08-08T02:32:58.265Z
Learning: 在 Taro 项目的 pnpm 工作区中,Vitest 相关依赖(vitest 和 vitest/coverage-istanbul)被管理在根目录的 package.json 中,而不是各个子包的 devDependencies 中。这是 monorepo 中依赖提升的标准做法。
📚 Learning: 2025-08-25T22:16:50.118Z
Learnt from: ianzone
Repo: NervJS/taro PR: 18150
File: packages/babel-plugin-transform-taroapi/tests/__mocks__/h5-definition.json:2356-2356
Timestamp: 2025-08-25T22:16:50.118Z
Learning: The file `packages/babel-plugin-transform-taroapi/tests/__mocks__/h5-definition.json` is auto-generated by the post-build script `packages/taro-platform-h5/scripts/post-build.mjs`, which copies content from `taro-platform-h5/dist/definition.json`. This file should not be manually edited.
Applied to files:
packages/taro-h5/__tests__/base/network.test.tspackages/taro-h5/__tests__/base/system.test.tspackages/taro-h5/__tests__/wxml/index.test.tspackages/taro-h5/__tests__/location/index.test.tspackages/taro-h5/__mocks__/setEnv.tspackages/taro-h5/vitest.config.mtspackages/taro-h5/__tests__/network/request.test.tspackages/taro-h5/__tests__/network/websocket.test.tspackages/taro-h5/__tests__/ui/navigation.test.tspackages/taro-h5/__tests__/ui/interaction/toast.test.tspackages/taro-h5/__tests__/storage/index.test.tspackages/taro-h5/package.jsonpackages/taro-h5/__tests__/ui/tab-bar.test.tsxpackages/taro-h5/__tests__/ui/interaction/loading.test.tspackages/taro-h5/__tests__/ui/interaction/modal.test.ts
📚 Learning: 2025-08-08T02:32:58.265Z
Learnt from: ianzone
Repo: NervJS/taro PR: 18146
File: packages/babel-plugin-transform-react-jsx-to-rn-stylesheet/package.json:12-14
Timestamp: 2025-08-08T02:32:58.265Z
Learning: 在 Taro 项目的 pnpm 工作区中,Vitest 相关依赖(vitest 和 vitest/coverage-istanbul)被管理在根目录的 package.json 中,而不是各个子包的 devDependencies 中。这是 monorepo 中依赖提升的标准做法。
Applied to files:
packages/taro-h5/__tests__/base/network.test.tspackages/taro-h5/__tests__/base/system.test.tspackages/taro-h5/__tests__/wxml/index.test.tspackages/taro-h5/__tests__/location/index.test.tspackages/taro-h5/vitest.config.mtspackages/taro-h5/__tests__/network/request.test.tspackages/taro-h5/__tests__/network/websocket.test.tspackages/taro-h5/__tests__/ui/navigation.test.tspackages/taro-h5/__tests__/ui/interaction/toast.test.tspackages/taro-h5/__tests__/storage/index.test.tspackages/taro-h5/package.jsonpackages/taro-h5/__tests__/ui/tab-bar.test.tsxpackages/taro-h5/__tests__/ui/interaction/loading.test.tspackages/taro-h5/__tests__/ui/interaction/modal.test.ts
📚 Learning: 2025-11-24T08:49:07.365Z
Learnt from: ianzone
Repo: NervJS/taro PR: 18649
File: packages/taroize/src/wxml.ts:731-731
Timestamp: 2025-11-24T08:49:07.365Z
Learning: 在 packages/taroize/src/wxml.ts 中,prettier.format() 返回值的 `as string` 类型断言是必要的,因为需要将结果重新赋值给类型为 `string | undefined` 的变量,而 prettier.format() 的返回类型可能是 `string | Promise<string>`,TypeScript 无法自动收窄类型。
Applied to files:
packages/taro-h5/__tests__/wxml/index.test.ts
📚 Learning: 2025-05-25T18:02:31.387Z
Learnt from: ianzone
Repo: NervJS/taro PR: 17746
File: packages/taro-runtime/tsdown.config.ts:10-16
Timestamp: 2025-05-25T18:02:31.387Z
Learning: 在 taro-runtime 包的 tsdown 配置中,必须禁用 treeshake 来保留 dom-external/index.js 文件。
Applied to files:
packages/taro-h5/__tests__/wxml/index.test.tspackages/taro-h5/__mocks__/setEnv.tspackages/taro-h5/vitest.config.mtspackages/taro-h5/package.json
📚 Learning: 2025-11-21T07:15:22.634Z
Learnt from: ianzone
Repo: NervJS/taro PR: 18646
File: packages/taro/package.json:40-40
Timestamp: 2025-11-21T07:15:22.634Z
Learning: 在 tarojs/taro 包中添加 vite 作为 devDependency 是为了让 tarojs/vite-runner 能够依赖正确的 vite 类型版本,确保 monorepo 中的类型兼容性。
Applied to files:
packages/taro-h5/__tests__/wxml/index.test.tspackages/taro-h5/vitest.config.mtspackages/taro-h5/package.json
📚 Learning: 2025-05-06T06:55:44.077Z
Learnt from: Single-Dancer
Repo: NervJS/taro PR: 17653
File: packages/taro-components-advanced/src/components/water-flow/node.ts:83-95
Timestamp: 2025-05-06T06:55:44.077Z
Learning: 在 Taro 的 getRectSizeSync 函数中,如果找不到指定的节点,函数会一直处于 pending 状态而不是抛出错误。在这种情况下,使用 try/catch 处理不够充分,需要添加超时处理如 Promise.race 来避免无限等待。
Applied to files:
packages/taro-h5/__tests__/wxml/index.test.ts
📚 Learning: 2025-06-23T00:09:31.233Z
Learnt from: ianzone
Repo: NervJS/taro PR: 17842
File: packages/jest-helper/tsconfig.json:9-9
Timestamp: 2025-06-23T00:09:31.233Z
Learning: 在 jest-helper 包中,src 目录下没有 __tests__ 测试目录,只包含 resolver.ts、sequencer.ts 和 snapshot 目录。不要假设包中存在测试目录结构。
Applied to files:
packages/taro-h5/__mocks__/setEnv.tspackages/taro-h5/vitest.config.mtspackages/taro-h5/__tests__/ui/interaction/toast.test.tspackages/taro-h5/__tests__/storage/index.test.tspackages/taro-h5/package.jsonpackages/taro-h5/__tests__/ui/interaction/loading.test.ts
📚 Learning: 2025-09-05T18:40:45.775Z
Learnt from: ianzone
Repo: NervJS/taro PR: 18150
File: packages/taro-platform-harmony-hybrid/package.json:43-45
Timestamp: 2025-09-05T18:40:45.775Z
Learning: 在 tarojs/plugin-platform-harmony-hybrid 包中,tarojs/components-library-react、tarojs/components-library-solid 和 tarojs/components-library-vue3 必须作为直接依赖(dependencies)而不能作为 peer 依赖,因为插件源码中有对这些包的直接引用,包括 componentAdapter* getter 方法和 webpack 别名配置。
Applied to files:
packages/taro-h5/package.json
🧬 Code graph analysis (3)
packages/taro-h5/__tests__/network/request.test.ts (1)
packages/taro-plugin-http/src/runtime/XMLHttpRequest.ts (1)
err(316-344)
packages/taro-h5/__tests__/ui/navigation.test.ts (2)
packages/taro-h5/__tests__/utils.ts (1)
buildApp(64-78)packages/taro-router/src/router/navigation-bar.ts (1)
loadingElement(66-69)
packages/taro-h5/__tests__/ui/tab-bar.test.tsx (1)
packages/taro-h5/__tests__/utils.ts (1)
buildApp(64-78)
🪛 ast-grep (0.40.0)
packages/taro-h5/__tests__/wxml/index.test.ts
[warning] 34-34: Direct modification of innerHTML or outerHTML properties detected. Modifying these properties with unsanitized user input can lead to XSS vulnerabilities. Use safe alternatives or sanitize content first.
Context: pageDOM.innerHTML = '
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://owasp.org/www-community/xss-filter-evasion-cheatsheet
- https://cwe.mitre.org/data/definitions/79.html
(dom-content-modification)
[warning] 56-59: Direct modification of innerHTML or outerHTML properties detected. Modifying these properties with unsanitized user input can lead to XSS vulnerabilities. Use safe alternatives or sanitize content first.
Context: pageDOM.innerHTML = <div id="box__a" class="box" data-url="xyz">box1</div> <div id="box__b" class="box" data-url="xxx" data-key="uzi">box1</div>
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://owasp.org/www-community/xss-filter-evasion-cheatsheet
- https://cwe.mitre.org/data/definitions/79.html
(dom-content-modification)
[warning] 119-122: Direct modification of innerHTML or outerHTML properties detected. Modifying these properties with unsanitized user input can lead to XSS vulnerabilities. Use safe alternatives or sanitize content first.
Context: pageDOM.innerHTML = <div id="box__a" class="box" data-url="xyz">box1</div> <div id="box__b" class="box" data-url="xxx" data-key="uzi">box1</div>
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://owasp.org/www-community/xss-filter-evasion-cheatsheet
- https://cwe.mitre.org/data/definitions/79.html
(dom-content-modification)
[warning] 145-145: Direct modification of innerHTML or outerHTML properties detected. Modifying these properties with unsanitized user input can lead to XSS vulnerabilities. Use safe alternatives or sanitize content first.
Context: pageDOM.innerHTML = '
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://owasp.org/www-community/xss-filter-evasion-cheatsheet
- https://cwe.mitre.org/data/definitions/79.html
(dom-content-modification)
[warning] 173-176: Direct modification of innerHTML or outerHTML properties detected. Modifying these properties with unsanitized user input can lead to XSS vulnerabilities. Use safe alternatives or sanitize content first.
Context: pageDOM.innerHTML = <div id="box__a" class="box" data-url="xyz">box1</div> <div id="box__b" class="box" data-url="xxx" data-key="uzi">box1</div>
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://owasp.org/www-community/xss-filter-evasion-cheatsheet
- https://cwe.mitre.org/data/definitions/79.html
(dom-content-modification)
[warning] 34-34: Direct HTML content assignment detected. Modifying innerHTML, outerHTML, or using document.write with unsanitized content can lead to XSS vulnerabilities. Use secure alternatives like textContent or sanitize HTML with libraries like DOMPurify.
Context: pageDOM.innerHTML = '
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://www.dhairyashah.dev/posts/why-innerhtml-is-a-bad-idea-and-how-to-avoid-it/
- https://cwe.mitre.org/data/definitions/79.html
(unsafe-html-content-assignment)
[warning] 56-59: Direct HTML content assignment detected. Modifying innerHTML, outerHTML, or using document.write with unsanitized content can lead to XSS vulnerabilities. Use secure alternatives like textContent or sanitize HTML with libraries like DOMPurify.
Context: pageDOM.innerHTML = <div id="box__a" class="box" data-url="xyz">box1</div> <div id="box__b" class="box" data-url="xxx" data-key="uzi">box1</div>
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://www.dhairyashah.dev/posts/why-innerhtml-is-a-bad-idea-and-how-to-avoid-it/
- https://cwe.mitre.org/data/definitions/79.html
(unsafe-html-content-assignment)
[warning] 119-122: Direct HTML content assignment detected. Modifying innerHTML, outerHTML, or using document.write with unsanitized content can lead to XSS vulnerabilities. Use secure alternatives like textContent or sanitize HTML with libraries like DOMPurify.
Context: pageDOM.innerHTML = <div id="box__a" class="box" data-url="xyz">box1</div> <div id="box__b" class="box" data-url="xxx" data-key="uzi">box1</div>
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://www.dhairyashah.dev/posts/why-innerhtml-is-a-bad-idea-and-how-to-avoid-it/
- https://cwe.mitre.org/data/definitions/79.html
(unsafe-html-content-assignment)
[warning] 145-145: Direct HTML content assignment detected. Modifying innerHTML, outerHTML, or using document.write with unsanitized content can lead to XSS vulnerabilities. Use secure alternatives like textContent or sanitize HTML with libraries like DOMPurify.
Context: pageDOM.innerHTML = '
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://www.dhairyashah.dev/posts/why-innerhtml-is-a-bad-idea-and-how-to-avoid-it/
- https://cwe.mitre.org/data/definitions/79.html
(unsafe-html-content-assignment)
[warning] 173-176: Direct HTML content assignment detected. Modifying innerHTML, outerHTML, or using document.write with unsanitized content can lead to XSS vulnerabilities. Use secure alternatives like textContent or sanitize HTML with libraries like DOMPurify.
Context: pageDOM.innerHTML = <div id="box__a" class="box" data-url="xyz">box1</div> <div id="box__b" class="box" data-url="xxx" data-key="uzi">box1</div>
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://www.dhairyashah.dev/posts/why-innerhtml-is-a-bad-idea-and-how-to-avoid-it/
- https://cwe.mitre.org/data/definitions/79.html
(unsafe-html-content-assignment)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
- GitHub Check: CodeQL analysis (javascript-typescript)
- GitHub Check: Agent
- GitHub Check: Build Rust Binding / stable - x86_64-unknown-linux-musl
- GitHub Check: Build Rust Binding / stable - aarch64-apple-darwin
- GitHub Check: Build Rust Binding / stable - x86_64-apple-darwin
- GitHub Check: Build Rust Binding / stable - x86_64-pc-windows-msvc
- GitHub Check: Build Rust Binding / stable - x86_64-unknown-linux-gnu
- GitHub Check: Build Rust WASM / stable - wasm32-wasi
🔇 Additional comments (32)
packages/taro-h5/__mocks__/setEnv.ts (1)
1-9: 测试环境配置正确!环境变量设置合理,使用
@testing-library/jest-dom扩展 DOM 断言功能是标准做法。此文件将作为 Vitest 的 setupFiles 使用,确保测试环境的一致性。packages/taro-h5/__tests__/ui/interaction/toast.test.ts (2)
2-2: LGTM!测试框架迁移正确。已正确从 Jest 迁移到 Vitest,导入了必要的测试工具。
8-10: Mock 函数替换正确。所有
jest.fn()已正确替换为vi.fn(),与 Vitest 的 API 保持一致。packages/taro-h5/package.json (2)
27-30: 测试脚本已正确迁移到 Vitest。所有测试命令已从 Jest 更新为 Vitest,命令参数也相应调整。配置简洁明了。
59-70: 依赖项更新合理。
- 添加了 Rollup 相关插件以支持构建配置
@testing-library/jest-dom升级到 ^6.6.3- 新增
jsdom用于 Vitest 的 DOM 测试环境- 移除了 Jest 特定的依赖包
基于项目学习经验,Vitest 核心依赖在根目录的 package.json 中管理,这是 monorepo 中的标准做法。
packages/taro-h5/__tests__/ui/interaction/modal.test.ts (4)
2-2: LGTM!测试框架导入正确。已正确导入 Vitest 的
vi工具用于创建 mock 函数。
242-244: 颜色断言已更新为 RGB 值。颜色断言从颜色名称(yellow、green)更新为明确的 RGB 值,这使得断言更加精确和可预测。
247-266: 异步测试模式已优化。测试从使用
done回调改为返回 Promise,这是更现代和清晰的异步测试模式。Line 262 使用toBeTruthy()而非toBeVisible()来检查 confirm 按钮的存在性。
267-287: 空标题场景测试已改进。测试模式已更新为 Promise 风格,提高了代码可读性。颜色断言使用 RGB 值确保跨浏览器的一致性。
packages/taro-h5/__tests__/base/system.test.ts (2)
2-2: LGTM!Vitest 导入正确。测试文件已正确迁移到 Vitest。
24-25: Mock 函数已正确更新。所有 mock 函数已从
jest.fn()迁移到vi.fn()。packages/taro-h5/__tests__/ui/interaction/loading.test.ts (2)
2-2: LGTM!测试导入已迁移。已正确从 Jest 迁移到 Vitest。
6-8: Mock 函数替换正确。所有测试中的 mock 函数已正确更新为 Vitest API。
packages/taro-h5/__tests__/location/index.test.ts (3)
2-2: LGTM!Vitest 导入正确。测试文件已成功迁移到 Vitest。
6-23: Console mock 和 geolocation mock 已正确更新。使用
vi.spyOn()替代 Jest 的 spy 机制,并正确 mock 了navigator.geolocation.getCurrentPosition。
26-28: 添加了测试清理逻辑。在
afterEach中使用vi.restoreAllMocks()恢复所有 mock,这是良好的测试实践,确保测试之间的隔离性。packages/taro-h5/__tests__/storage/index.test.ts (3)
2-2: LGTM!Vitest 导入正确。测试框架已成功迁移到 Vitest。
7-14: Console mock 和清理逻辑配置正确。使用
vi.spyOn()mock console 方法,并在afterEach中使用vi.restoreAllMocks()进行清理,确保测试隔离性。
36-38: Mock 函数已全面更新。所有测试用例中的
jest.fn()已正确替换为vi.fn(),与 Vitest API 保持一致。packages/taro-h5/__tests__/ui/tab-bar.test.tsx (1)
1-10: Jest 到 Vitest 迁移正确。导入
vi并使用vi.resetAllMocks()替换 Jest API 的方式正确。async测试函数配合await的模式比原来的done回调更清晰。packages/taro-h5/__tests__/ui/interaction/actionSheet.test.ts (2)
2-2: Vitest 导入正确。
189-189: 颜色断言更新正确。从
'red'改为'rgb(255, 0, 0)'是正确的,因为 jsdom 的getComputedStyle返回的是 RGB 格式的计算值。packages/taro-h5/__tests__/base/network.test.ts (1)
58-75: Promise 模式迁移正确。使用
new Promise<void>包装异步测试逻辑,并在回调中调用resolve()的方式正确。packages/taro-h5/__tests__/ui/navigation.test.ts (2)
9-16: Console spy 和清理模式正确。使用
vi.spyOn(console, 'log').mockImplementation(() => {})抑制测试中的控制台输出,并在afterEach中使用vi.restoreAllMocks()清理,这是 Vitest 的标准做法。
91-101: async/await 模式迁移良好。测试从 Promise 链式调用改为 async/await,代码更加清晰易读。
packages/taro-h5/__tests__/network/request.test.ts (2)
4-20: Fetch mock 辅助函数设计良好。
mockFetchOnce和mockFetchReject辅助函数封装了常见的 mock 场景,提高了代码复用性。
163-183: AbortSignal 处理逻辑实现正确。mock 实现正确处理了
AbortSignal的aborted状态和abort事件监听,能够准确模拟请求超时被取消的场景。packages/taro-h5/vitest.config.mts (1)
5-22: Vitest 配置正确且完整。配置包含了必要的设置:
globals: true启用全局测试 APIjsdom环境用于 DOM 测试- 正确的模块别名配置
- Istanbul 覆盖率提供者
根据已有 learnings,Vitest 依赖在 monorepo 根目录的 package.json 中管理,这是正确的做法。
packages/taro-h5/__tests__/wxml/index.test.ts (2)
33-52: Promise 模式迁移正确。使用
return new Promise<void>(resolve => { ... resolve() })包装异步选择器查询测试是正确的做法。
34-35: innerHTML 使用在测试环境中是安全的。静态分析工具标记了
innerHTML赋值为潜在的 XSS 风险。但在测试代码中,这些都是硬编码的测试 fixture,不涉及用户输入,因此是安全的。可以忽略这些警告。Also applies to: 56-59, 119-122, 145-145, 173-176
packages/taro-h5/__tests__/network/websocket.test.ts (2)
6-21: WebSocket mock 设置和清理模式正确。保存原始
WebSocket并在afterEach中恢复,同时设置globalThis.WebSocket和window.WebSocket确保了兼容性。Console spy 模式与其他测试文件保持一致。
115-175: WebSocket 基础功能测试迁移正确。测试使用
new Promise<void>包装,通过mock-socket的Server模拟 WebSocket 服务器。vi.spyOn用于验证send和close方法的调用,resolve()在onClose回调中调用以确保测试完成。
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
packages/taro-h5/vitest.config.ts (1)
1-2: 关于在 TS 配置里使用__dirname的兼容性小提醒(可选优化)当前使用
resolve(__dirname, ...)写法在大多数场景下是 OK 的,但有一个潜在点可以留意一下:
- 如果后续 Vitest/Vite 的配置加载方式完全切到原生 ESM(或仓库统一把配置当 ESM 处理),
__dirname在 Node ESM 中默认是不存在的,需要自己基于import.meta.url计算。- 如果仓库里其他
vitest.config.ts/vite.config.ts也都是__dirname + resolve的写法,并且在当前 Node/Vitest 版本下工作正常,那保持一致没有问题,只需要在升级 Node / Vitest 时多留意一下即可。如果你想提前做成“无论 CJS 还是 ESM 都安全”的写法,可以考虑改成类似这种(可选,不是必须):
import { resolve } from 'node:path' import { fileURLToPath } from 'node:url' const __dirname = fileURLToPath(new URL('.', import.meta.url)) export default defineConfig({ test: { alias: { '@tarojs/taro': resolve(__dirname, 'src/index.ts'), // 其余 alias 同现有写法 }, }, })如果当前仓库工具链已经验证过
__dirname可用,这条可以暂时当作“备忘录”,等未来升级 Node/Vitest 时再视情况统一调整即可。Also applies to: 11-18
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
packages/taro-h5/vitest.config.ts(1 hunks)
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: ianzone
Repo: NervJS/taro PR: 18146
File: packages/babel-plugin-transform-react-jsx-to-rn-stylesheet/package.json:12-14
Timestamp: 2025-08-08T02:32:58.265Z
Learning: 在 Taro 项目的 pnpm 工作区中,Vitest 相关依赖(vitest 和 vitest/coverage-istanbul)被管理在根目录的 package.json 中,而不是各个子包的 devDependencies 中。这是 monorepo 中依赖提升的标准做法。
📚 Learning: 2025-08-25T22:16:50.118Z
Learnt from: ianzone
Repo: NervJS/taro PR: 18150
File: packages/babel-plugin-transform-taroapi/tests/__mocks__/h5-definition.json:2356-2356
Timestamp: 2025-08-25T22:16:50.118Z
Learning: The file `packages/babel-plugin-transform-taroapi/tests/__mocks__/h5-definition.json` is auto-generated by the post-build script `packages/taro-platform-h5/scripts/post-build.mjs`, which copies content from `taro-platform-h5/dist/definition.json`. This file should not be manually edited.
Applied to files:
packages/taro-h5/vitest.config.ts
📚 Learning: 2025-08-08T02:32:58.265Z
Learnt from: ianzone
Repo: NervJS/taro PR: 18146
File: packages/babel-plugin-transform-react-jsx-to-rn-stylesheet/package.json:12-14
Timestamp: 2025-08-08T02:32:58.265Z
Learning: 在 Taro 项目的 pnpm 工作区中,Vitest 相关依赖(vitest 和 vitest/coverage-istanbul)被管理在根目录的 package.json 中,而不是各个子包的 devDependencies 中。这是 monorepo 中依赖提升的标准做法。
Applied to files:
packages/taro-h5/vitest.config.ts
📚 Learning: 2025-11-21T07:15:22.634Z
Learnt from: ianzone
Repo: NervJS/taro PR: 18646
File: packages/taro/package.json:40-40
Timestamp: 2025-11-21T07:15:22.634Z
Learning: 在 tarojs/taro 包中添加 vite 作为 devDependency 是为了让 tarojs/vite-runner 能够依赖正确的 vite 类型版本,确保 monorepo 中的类型兼容性。
Applied to files:
packages/taro-h5/vitest.config.ts
📚 Learning: 2025-06-23T00:09:31.233Z
Learnt from: ianzone
Repo: NervJS/taro PR: 17842
File: packages/jest-helper/tsconfig.json:9-9
Timestamp: 2025-06-23T00:09:31.233Z
Learning: 在 jest-helper 包中,src 目录下没有 __tests__ 测试目录,只包含 resolver.ts、sequencer.ts 和 snapshot 目录。不要假设包中存在测试目录结构。
Applied to files:
packages/taro-h5/vitest.config.ts
📚 Learning: 2025-05-25T18:02:31.387Z
Learnt from: ianzone
Repo: NervJS/taro PR: 17746
File: packages/taro-runtime/tsdown.config.ts:10-16
Timestamp: 2025-05-25T18:02:31.387Z
Learning: 在 taro-runtime 包的 tsdown 配置中,必须禁用 treeshake 来保留 dom-external/index.js 文件。
Applied to files:
packages/taro-h5/vitest.config.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Build Rust Binding / stable - aarch64-apple-darwin
- GitHub Check: Build Rust Binding / stable - x86_64-unknown-linux-gnu
- GitHub Check: Build Rust Binding / stable - x86_64-pc-windows-msvc
- GitHub Check: Build Rust Binding / stable - x86_64-apple-darwin
- GitHub Check: Build Rust WASM / stable - wasm32-wasi
🔇 Additional comments (1)
packages/taro-h5/vitest.config.ts (1)
5-22: Vitest 配置整体合理,alias 与覆盖率设置与 H5 测试场景匹配这一版配置整体看起来很干净、合理:
environment: 'jsdom'+globals: true、include模式和原来 Jest 的约定基本一致,迁移成本低。setupFiles: ['__mocks__/setEnv.ts']把环境初始化集中在一个文件里,也方便后续扩展。- 多个
alias把@tarojs/taro/@tarojs/taro-h5/@tarojs/shared以及各个 framework runtime、platform都指到了 H5 包内部或 monorepo 下的实现/模拟,符合在单包下跑集成型单测的思路。coverage: { provider: 'istanbul' }也和仓库里之前使用vitest/coverage-istanbul的习惯对齐(根据既有 learnings),不在子包重复声明依赖是对的。建议你本地再确认两点即可:
- 跑一遍
pnpm test/ 对应 H5 测试命令,确保所有 alias 都能正确解析到目标文件(特别是@tarojs/shared的跨包路径)。- 确认根
package.json中已包含@vitest/coverage-istanbul或对应覆盖率依赖,避免 CI 上只在 H5 包下跑测试时出现 provider 缺失的问题。整体上这份配置可以直接合入,后续如有新增 alias 也可以按这个模式扩展。
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (1)
packages/taro-h5/__tests__/network/websocket.test.ts (1)
139-142: 移除调试日志这些
console.log语句是调试遗留代码,不应提交到测试代码中。- // eslint-disable-next-line no-console - console.log('Task:', task) - // eslint-disable-next-line no-console - console.log('Task WS:', task?.ws)
🧹 Nitpick comments (7)
packages/taro-h5/__tests__/wxml/index.test.ts (1)
33-209: 测试结构迁移成功!所有测试正确地从回调模式重构为基于 Promise 的异步模式,测试逻辑保持不变。当前实现是有效的。
可选优化建议:如果希望代码更简洁,可以考虑使用 async/await 模式。例如:
- test('should get single element\'s boundingClientRect', () => { - return new Promise<void>(resolve => { + test('should get single element\'s boundingClientRect', async () => { + await new Promise<void>(resolve => { pageDOM.innerHTML = '<div id="box__a" data-url="xxx">box1</div>' const query = Taro.createSelectorQuery() query.select('#box__a').boundingClientRect(rect => { expect(rect).toEqual({ // ... }) resolve() }).exec() }) - })不过这只是风格偏好,当前实现完全可以接受。
packages/taro-h5/__tests__/location/index.test.ts (1)
37-37: 建议清理注释掉的断言代码。测试中存在被注释掉的
console.error断言(第 37 行和第 107-108 行)。建议:
- 如果这些断言不再需要,应该删除这些注释
- 如果这些断言仍然有效,应该取消注释并更新为 Vitest 的断言方式
Also applies to: 107-108
packages/taro-h5/__tests__/ui/navigation.test.ts (2)
61-63: 可选:抽一个小工具函数复用这组三个回调 mock这一组 success/fail/complete 的 vi.fn() 定义在文件内多处出现,未来如果继续新增类似用例,可以考虑抽一个工厂函数(例如 createCallbacks())来减少重复;当前实现已经足够清晰,可视为后续优化项。
85-87: 建议在本 describe 中也恢复 console 的 spy,避免跨文件泄漏这里的 beforeEach 同样对 console.log/error/warn 做了 vi.spyOn,但本 describe 内没有对应的 afterEach 调用 vi.restoreAllMocks()。如果 Vitest 配置里没有启用自动 restoreMocks,这些 stub 可能会“静音”后续其他测试文件的 console 输出。建议在该 describe 下补充:
afterEach(() => { vi.restoreAllMocks() })或在最外层统一管理一次,避免潜在的副作用。
packages/taro-h5/__tests__/ui/tab-bar.test.tsx (3)
12-36: set/removeTabBarBadge 用例的异步改写正确,注释断言可适当整理先通过
eventCenter.once('__taroSetTabBarBadge')/('__taroRemoveTabBarBadge')注入成功回调,再等待Taro.setTabBarBadge/Taro.removeTabBarBadge返回并断言errMsg,语义与原先逻辑一致,没有明显竞态或遗漏。唯一的小点是多段 DOM 相关断言已被注释,如长期不用可以考虑删掉或加上说明,减少后续阅读成本。
62-80: show/hideTabBar 测试的异步写法简洁且正确
__taroHideTabBar与__taroShowTabBar的事件监听及对hideTabBar/showTabBar返回结果的断言衔接正常,仍能验证隐藏/显示流程成功。下面同样有注释掉的 DOM 断言,和前一个用例类似,可视实际需要后续统一清理或恢复。
109-113: switchTab 测试建议避免显式使用 any 提升类型安全等待
Taro.switchTab返回并检查errMsg的逻辑本身是正确的。不过这里将res标注为any会遮蔽潜在的类型问题,如果 Taro 的类型定义已声明返回类型,建议依赖类型推断或直接写具体类型,而不是显式any。可以考虑改成:
- const res: any = await Taro.switchTab({ + const res = await Taro.switchTab({
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (17)
packages/taro-h5/__mocks__/setEnv.ts(1 hunks)packages/taro-h5/__tests__/base/index.test.ts(1 hunks)packages/taro-h5/__tests__/base/network.test.ts(2 hunks)packages/taro-h5/__tests__/base/pxTransform.test.ts(1 hunks)packages/taro-h5/__tests__/base/system.test.ts(2 hunks)packages/taro-h5/__tests__/location/index.test.ts(4 hunks)packages/taro-h5/__tests__/network/request.test.ts(7 hunks)packages/taro-h5/__tests__/network/websocket.test.ts(5 hunks)packages/taro-h5/__tests__/storage/index.test.ts(9 hunks)packages/taro-h5/__tests__/ui/animation.test.ts(1 hunks)packages/taro-h5/__tests__/ui/interaction/actionSheet.test.ts(9 hunks)packages/taro-h5/__tests__/ui/interaction/loading.test.ts(2 hunks)packages/taro-h5/__tests__/ui/interaction/modal.test.ts(11 hunks)packages/taro-h5/__tests__/ui/navigation.test.ts(4 hunks)packages/taro-h5/__tests__/ui/tab-bar.test.tsx(4 hunks)packages/taro-h5/__tests__/wxml/index.test.ts(3 hunks)packages/taro-h5/vitest.config.mts(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- packages/taro-h5/tests/base/pxTransform.test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- packages/taro-h5/tests/storage/index.test.ts
- packages/taro-h5/tests/base/network.test.ts
- packages/taro-h5/tests/ui/interaction/actionSheet.test.ts
🧰 Additional context used
🧠 Learnings (7)
📚 Learning: 2025-08-25T22:16:50.118Z
Learnt from: ianzone
Repo: NervJS/taro PR: 18150
File: packages/babel-plugin-transform-taroapi/tests/__mocks__/h5-definition.json:2356-2356
Timestamp: 2025-08-25T22:16:50.118Z
Learning: The file `packages/babel-plugin-transform-taroapi/tests/__mocks__/h5-definition.json` is auto-generated by the post-build script `packages/taro-platform-h5/scripts/post-build.mjs`, which copies content from `taro-platform-h5/dist/definition.json`. This file should not be manually edited.
Applied to files:
packages/taro-h5/__tests__/base/system.test.tspackages/taro-h5/__tests__/ui/tab-bar.test.tsxpackages/taro-h5/__tests__/base/index.test.tspackages/taro-h5/__tests__/ui/interaction/modal.test.tspackages/taro-h5/__tests__/network/websocket.test.tspackages/taro-h5/__tests__/ui/animation.test.tspackages/taro-h5/__mocks__/setEnv.tspackages/taro-h5/__tests__/network/request.test.tspackages/taro-h5/__tests__/location/index.test.tspackages/taro-h5/vitest.config.mtspackages/taro-h5/__tests__/ui/interaction/loading.test.tspackages/taro-h5/__tests__/ui/navigation.test.tspackages/taro-h5/__tests__/wxml/index.test.ts
📚 Learning: 2025-08-08T02:32:58.265Z
Learnt from: ianzone
Repo: NervJS/taro PR: 18146
File: packages/babel-plugin-transform-react-jsx-to-rn-stylesheet/package.json:12-14
Timestamp: 2025-08-08T02:32:58.265Z
Learning: 在 Taro 项目的 pnpm 工作区中,Vitest 相关依赖(vitest 和 vitest/coverage-istanbul)被管理在根目录的 package.json 中,而不是各个子包的 devDependencies 中。这是 monorepo 中依赖提升的标准做法。
Applied to files:
packages/taro-h5/__tests__/base/system.test.tspackages/taro-h5/__tests__/ui/tab-bar.test.tsxpackages/taro-h5/__tests__/base/index.test.tspackages/taro-h5/__tests__/ui/interaction/modal.test.tspackages/taro-h5/__tests__/network/websocket.test.tspackages/taro-h5/__tests__/ui/animation.test.tspackages/taro-h5/__mocks__/setEnv.tspackages/taro-h5/__tests__/network/request.test.tspackages/taro-h5/__tests__/location/index.test.tspackages/taro-h5/vitest.config.mtspackages/taro-h5/__tests__/ui/interaction/loading.test.tspackages/taro-h5/__tests__/ui/navigation.test.tspackages/taro-h5/__tests__/wxml/index.test.ts
📚 Learning: 2025-11-21T07:15:22.634Z
Learnt from: ianzone
Repo: NervJS/taro PR: 18646
File: packages/taro/package.json:40-40
Timestamp: 2025-11-21T07:15:22.634Z
Learning: 在 tarojs/taro 包中添加 vite 作为 devDependency 是为了让 tarojs/vite-runner 能够依赖正确的 vite 类型版本,确保 monorepo 中的类型兼容性。
Applied to files:
packages/taro-h5/__tests__/base/index.test.tspackages/taro-h5/__mocks__/setEnv.tspackages/taro-h5/vitest.config.mtspackages/taro-h5/__tests__/wxml/index.test.ts
📚 Learning: 2025-06-23T00:09:31.233Z
Learnt from: ianzone
Repo: NervJS/taro PR: 17842
File: packages/jest-helper/tsconfig.json:9-9
Timestamp: 2025-06-23T00:09:31.233Z
Learning: 在 jest-helper 包中,src 目录下没有 __tests__ 测试目录,只包含 resolver.ts、sequencer.ts 和 snapshot 目录。不要假设包中存在测试目录结构。
Applied to files:
packages/taro-h5/__tests__/base/index.test.tspackages/taro-h5/__mocks__/setEnv.tspackages/taro-h5/__tests__/location/index.test.tspackages/taro-h5/vitest.config.mtspackages/taro-h5/__tests__/ui/interaction/loading.test.ts
📚 Learning: 2025-05-25T18:02:31.387Z
Learnt from: ianzone
Repo: NervJS/taro PR: 17746
File: packages/taro-runtime/tsdown.config.ts:10-16
Timestamp: 2025-05-25T18:02:31.387Z
Learning: 在 taro-runtime 包的 tsdown 配置中,必须禁用 treeshake 来保留 dom-external/index.js 文件。
Applied to files:
packages/taro-h5/__mocks__/setEnv.tspackages/taro-h5/vitest.config.mtspackages/taro-h5/__tests__/wxml/index.test.ts
📚 Learning: 2025-11-24T08:49:07.365Z
Learnt from: ianzone
Repo: NervJS/taro PR: 18649
File: packages/taroize/src/wxml.ts:731-731
Timestamp: 2025-11-24T08:49:07.365Z
Learning: 在 packages/taroize/src/wxml.ts 中,prettier.format() 返回值的 `as string` 类型断言是必要的,因为需要将结果重新赋值给类型为 `string | undefined` 的变量,而 prettier.format() 的返回类型可能是 `string | Promise<string>`,TypeScript 无法自动收窄类型。
Applied to files:
packages/taro-h5/__tests__/wxml/index.test.ts
📚 Learning: 2025-05-06T06:55:44.077Z
Learnt from: Single-Dancer
Repo: NervJS/taro PR: 17653
File: packages/taro-components-advanced/src/components/water-flow/node.ts:83-95
Timestamp: 2025-05-06T06:55:44.077Z
Learning: 在 Taro 的 getRectSizeSync 函数中,如果找不到指定的节点,函数会一直处于 pending 状态而不是抛出错误。在这种情况下,使用 try/catch 处理不够充分,需要添加超时处理如 Promise.race 来避免无限等待。
Applied to files:
packages/taro-h5/__tests__/wxml/index.test.ts
🧬 Code graph analysis (1)
packages/taro-h5/__tests__/ui/navigation.test.ts (3)
packages/taro-h5/__tests__/utils.ts (1)
buildApp(64-78)packages/jest-helper/src/snapshot/serializers.ts (1)
test(52-52)packages/taro-router/src/router/navigation-bar.ts (1)
loadingElement(66-69)
🪛 ast-grep (0.40.0)
packages/taro-h5/__tests__/wxml/index.test.ts
[warning] 34-34: Direct modification of innerHTML or outerHTML properties detected. Modifying these properties with unsanitized user input can lead to XSS vulnerabilities. Use safe alternatives or sanitize content first.
Context: pageDOM.innerHTML = '
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://owasp.org/www-community/xss-filter-evasion-cheatsheet
- https://cwe.mitre.org/data/definitions/79.html
(dom-content-modification)
[warning] 56-59: Direct modification of innerHTML or outerHTML properties detected. Modifying these properties with unsanitized user input can lead to XSS vulnerabilities. Use safe alternatives or sanitize content first.
Context: pageDOM.innerHTML = <div id="box__a" class="box" data-url="xyz">box1</div> <div id="box__b" class="box" data-url="xxx" data-key="uzi">box1</div>
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://owasp.org/www-community/xss-filter-evasion-cheatsheet
- https://cwe.mitre.org/data/definitions/79.html
(dom-content-modification)
[warning] 119-122: Direct modification of innerHTML or outerHTML properties detected. Modifying these properties with unsanitized user input can lead to XSS vulnerabilities. Use safe alternatives or sanitize content first.
Context: pageDOM.innerHTML = <div id="box__a" class="box" data-url="xyz">box1</div> <div id="box__b" class="box" data-url="xxx" data-key="uzi">box1</div>
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://owasp.org/www-community/xss-filter-evasion-cheatsheet
- https://cwe.mitre.org/data/definitions/79.html
(dom-content-modification)
[warning] 145-145: Direct modification of innerHTML or outerHTML properties detected. Modifying these properties with unsanitized user input can lead to XSS vulnerabilities. Use safe alternatives or sanitize content first.
Context: pageDOM.innerHTML = '
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://owasp.org/www-community/xss-filter-evasion-cheatsheet
- https://cwe.mitre.org/data/definitions/79.html
(dom-content-modification)
[warning] 173-176: Direct modification of innerHTML or outerHTML properties detected. Modifying these properties with unsanitized user input can lead to XSS vulnerabilities. Use safe alternatives or sanitize content first.
Context: pageDOM.innerHTML = <div id="box__a" class="box" data-url="xyz">box1</div> <div id="box__b" class="box" data-url="xxx" data-key="uzi">box1</div>
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://owasp.org/www-community/xss-filter-evasion-cheatsheet
- https://cwe.mitre.org/data/definitions/79.html
(dom-content-modification)
[warning] 34-34: Direct HTML content assignment detected. Modifying innerHTML, outerHTML, or using document.write with unsanitized content can lead to XSS vulnerabilities. Use secure alternatives like textContent or sanitize HTML with libraries like DOMPurify.
Context: pageDOM.innerHTML = '
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://www.dhairyashah.dev/posts/why-innerhtml-is-a-bad-idea-and-how-to-avoid-it/
- https://cwe.mitre.org/data/definitions/79.html
(unsafe-html-content-assignment)
[warning] 56-59: Direct HTML content assignment detected. Modifying innerHTML, outerHTML, or using document.write with unsanitized content can lead to XSS vulnerabilities. Use secure alternatives like textContent or sanitize HTML with libraries like DOMPurify.
Context: pageDOM.innerHTML = <div id="box__a" class="box" data-url="xyz">box1</div> <div id="box__b" class="box" data-url="xxx" data-key="uzi">box1</div>
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://www.dhairyashah.dev/posts/why-innerhtml-is-a-bad-idea-and-how-to-avoid-it/
- https://cwe.mitre.org/data/definitions/79.html
(unsafe-html-content-assignment)
[warning] 119-122: Direct HTML content assignment detected. Modifying innerHTML, outerHTML, or using document.write with unsanitized content can lead to XSS vulnerabilities. Use secure alternatives like textContent or sanitize HTML with libraries like DOMPurify.
Context: pageDOM.innerHTML = <div id="box__a" class="box" data-url="xyz">box1</div> <div id="box__b" class="box" data-url="xxx" data-key="uzi">box1</div>
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://www.dhairyashah.dev/posts/why-innerhtml-is-a-bad-idea-and-how-to-avoid-it/
- https://cwe.mitre.org/data/definitions/79.html
(unsafe-html-content-assignment)
[warning] 145-145: Direct HTML content assignment detected. Modifying innerHTML, outerHTML, or using document.write with unsanitized content can lead to XSS vulnerabilities. Use secure alternatives like textContent or sanitize HTML with libraries like DOMPurify.
Context: pageDOM.innerHTML = '
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://www.dhairyashah.dev/posts/why-innerhtml-is-a-bad-idea-and-how-to-avoid-it/
- https://cwe.mitre.org/data/definitions/79.html
(unsafe-html-content-assignment)
[warning] 173-176: Direct HTML content assignment detected. Modifying innerHTML, outerHTML, or using document.write with unsanitized content can lead to XSS vulnerabilities. Use secure alternatives like textContent or sanitize HTML with libraries like DOMPurify.
Context: pageDOM.innerHTML = <div id="box__a" class="box" data-url="xyz">box1</div> <div id="box__b" class="box" data-url="xxx" data-key="uzi">box1</div>
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://www.dhairyashah.dev/posts/why-innerhtml-is-a-bad-idea-and-how-to-avoid-it/
- https://cwe.mitre.org/data/definitions/79.html
(unsafe-html-content-assignment)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Build Rust Binding / stable - aarch64-apple-darwin
- GitHub Check: Build Rust Binding / stable - x86_64-unknown-linux-gnu
- GitHub Check: Build Rust Binding / stable - x86_64-apple-darwin
- GitHub Check: Build Rust Binding / stable - x86_64-pc-windows-msvc
- GitHub Check: Build Rust WASM / stable - wasm32-wasi
🔇 Additional comments (27)
packages/taro-h5/__tests__/base/system.test.ts (2)
2-2: LGTM!Vitest 导入语句正确,包含了测试所需的所有必要函数(
describe、expect、test、vi)。
24-25: LGTM!Mock 函数已正确从
jest.fn()迁移到vi.fn(),这是 Vitest 的等效替代方案。测试逻辑保持不变。packages/taro-h5/__tests__/wxml/index.test.ts (3)
3-3: 导入语句迁移正确!Vitest 的导入语句符合预期,包含了所有必要的测试工具。
24-24: Mock 重置迁移正确!使用
vi.resetAllMocks()是 Vitest 的正确 API,功能上与 Jest 等价。
34-34: 静态分析警告可以安全忽略静态分析工具标记了
innerHTML的使用,但这些都是测试夹具(test fixtures)的设置代码,使用的是硬编码的字面量字符串,不涉及用户输入。在测试上下文中,这种用法是安全且必要的,无 XSS 风险。Also applies to: 56-59, 119-122, 145-145, 173-176
packages/taro-h5/__tests__/location/index.test.ts (3)
2-2: 导入语句迁移正确!Vitest API 导入完整,包含了所有必要的测试工具函数。
5-28: 测试生命周期钩子迁移完善!
- Console 模拟正确地从 Jest 的 mock-console 迁移到 Vitest 的
vi.spyOn模式navigator.geolocation.getCurrentPosition正确使用vi.fn()- 新增的
afterEach钩子调用vi.restoreAllMocks()确保了测试之间的隔离性
56-56: Mock 函数迁移正确!所有
jest.fn()调用已正确替换为vi.fn(),mock 函数的行为和断言保持一致。Also applies to: 89-91
packages/taro-h5/__tests__/base/index.test.ts (1)
1-19: LGTM!Vitest 迁移正确,测试逻辑保持不变。
packages/taro-h5/__tests__/ui/animation.test.ts (1)
1-21: LGTM!Vitest 导入正确,测试逻辑保持一致。
packages/taro-h5/__mocks__/setEnv.ts (1)
1-9: LGTM!使用
@testing-library/jest-dom/vitest是 Vitest 环境下扩展 DOM 匹配器的正确方式。packages/taro-h5/__tests__/ui/interaction/loading.test.ts (1)
1-82: LGTM!Jest 到 Vitest 的迁移正确,
jest.fn()已替换为vi.fn(),测试逻辑保持不变。packages/taro-h5/vitest.config.mts (1)
1-23: LGTM!Vitest 配置完整且正确:
jsdom环境适用于 DOM 测试- 别名配置正确解析 monorepo 中的包路径
- Istanbul 覆盖率配置符合项目约定
基于 learnings,Vitest 依赖在 pnpm 工作区根目录统一管理,此配置符合该模式。
packages/taro-h5/__tests__/network/request.test.ts (2)
7-20: 辅助函数实现良好
mockFetchOnce和mockFetchReject封装了 fetch mock 逻辑,提高了测试代码的可读性和复用性。
163-183: Abort 测试实现正确新的
mockImplementationOnce实现正确处理了AbortSignal,包括立即中止检查和abort事件监听,符合真实的 fetch 行为。packages/taro-h5/__tests__/ui/interaction/modal.test.ts (2)
247-266: Promise 风格测试重构正确将
done回调转换为返回Promise<void>是 Vitest 推荐的异步测试写法,代码更清晰。
267-287: LGTM!测试重构为 Promise 风格,断言逻辑保持一致。
packages/taro-h5/__tests__/network/websocket.test.ts (2)
6-22: WebSocket Mock 设置完善正确保存和恢复原始
WebSocket,同时覆盖globalThis和window,确保测试隔离性。控制台 spy 抑制输出是良好实践。
115-175: Promise 风格重构正确测试从回调风格重构为
Promise<void>,事件处理流程清晰,正确使用vi.spyOn监听方法调用。packages/taro-h5/__tests__/ui/navigation.test.ts (4)
2-2: Vitest 导入方式与仓库用法保持一致从 vitest 引入 afterEach/beforeEach/describe/expect/test/vi 符合本 PR 的迁移目标,也契合 Taro 在 monorepo 根目录统一管理 Vitest 依赖的做法,无需在子包单独声明测试依赖。基于既有 learnings,这里是合理的调整。
9-15: 使用 vi.spyOn + vi.restoreAllMocks 管理 console 很合适在 beforeEach 中对 console.log/warn/error 做 spy,并在 afterEach 统一调用 vi.restoreAllMocks(),既能屏蔽测试噪音,又避免对其他用例造成副作用,实现简洁且语义清晰。
37-39: jest.fn → vi.fn 迁移正确将 success/fail/complete 全部替换为 vi.fn(),配合后面的 mock.calls 断言,行为与原来的 jest.fn 一致,迁移无功能性差异。
91-100: 异步用例改为 async/await 写法合理且更易读用 async/await 顺序调用 showNavigationBarLoading / hideNavigationBarLoading,并在中间、结束处分别断言 errMsg 与 DOM 中 loading 元素的存在/消失,语义清晰,等价于之前的 Promise 链写法,没有遗漏 await 或断言顺序问题。
packages/taro-h5/__tests__/ui/tab-bar.test.tsx (4)
2-10: Vitest 导入与 beforeEach 重置逻辑整体合理从 Jest 切到 Vitest 后,这里的导入和
vi.resetAllMocks()用法与原有用法保持一致,buildApp()仍在每个用例前调用,测试隔离性看起来没有回归风险。
38-60: show/hideTabBarRedDot 测试迁移后语义保持一致通过对
__taroShowTabBarRedDotHandler/__taroHideTabBarRedDotHandler注册一次性回调,再等待对应的 Taro API 返回并校验errMsg,能够覆盖成功分支,结构比回调链更直观,未看到行为变化风险。
82-93: setTabBarStyle 测试从回调式到直接等待结果的迁移是合理的先 mock
__taroSetTabBarStyle的成功回调,再调用Taro.setTabBarStyle并检查errMsg,既验证了 API 调用链路也保持了原有断言含义,传入的样式字段也都被覆盖到,逻辑上没有问题。
95-107: setTabBarItem 测试延续了原有校验路径对
__taroSetTabBarItem的事件 mock、setTabBarItem的参数(index、iconPath、selectedIconPath、text)以及返回errMsg的断言都完整,迁移后依然能有效验证 tabBarItem 设置成功。
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (6)
packages/taro-h5/__tests__/utils.ts (1)
5-6: 使用本地taro-frameworkmock 的改动整体合理,但需要确保接口同步从真实 runtime 切换到
../__mocks__/taro-framework可以让测试更稳定、避免依赖打包细节,这个方向没问题。不过有两点建议:
- 请确认 mock 中的
createReactApp在函数签名(参数顺序、可选参数、返回值结构)上与真实实现保持一致,避免因为 mock 简化过度导致测试语义偏离真实行为。- 建议在
__mocks__/taro-framework文件顶部加一行注释,说明该 mock 需要与@tarojs/plugin-framework-react的 runtime API 保持同步,后续有人修改 runtime 时更容易联动更新。packages/taro-h5/__tests__/ui/tab-bar.test.tsx (1)
1-114: tab-bar 用例迁移到 vi + async/await 整体合理这几个用例里对
Taro.*的调用统一改为async/await,配合eventCenter.once(... successHandler)的写法在语义上与原 Jest 版本一致且更直观;beforeEach中先vi.resetAllMocks()再buildApp()也有利于隔离状态。目前只校验errMsg,DOM 断言被注释掉,如果后续希望增强 UI 覆盖率,可以考虑在稳定后再逐步恢复这些断言。packages/taro-h5/__tests__/ui/navigation.test.ts (1)
84-101: 为 navigation loading 用例的 console spy 增加清理逻辑会更稳妥
showNavigationBarLoading / hideNavigationBarLoading这组用例的beforeEach中同样对console.log/warn/error做了vi.spyOn(...).mockImplementation,但本 describe 内没有对应的afterEach去vi.restoreAllMocks()。当前文件里影响不大,但会让 console mock 泄漏到之后的其他测试。建议比照上面的setNavigationBarTitledescribe,在这里也增加一次清理:describe('showNavigationBarLoading / hideNavigationBarLoading', () => { - beforeEach(() => { + beforeEach(() => { vi.spyOn(console, 'log').mockImplementation(() => {}) vi.spyOn(console, 'error').mockImplementation(() => {}) vi.spyOn(console, 'warn').mockImplementation(() => {}) buildApp() }) + + afterEach(() => { + vi.restoreAllMocks() + })packages/taro-h5/__tests__/base/network.test.ts (1)
58-76:onNetworkStatusChange用例可避免 1 秒真实定时器以提升测试速度当前用例通过
setTimeout(() => cbList.change(), 1000)触发回调,会让每次运行多等 1 秒,在 CI 或本地 watch 模式下都会明显拖慢执行,而且如果默认超时时间较紧也有潜在风险。由于Taro.onNetworkStatusChange注册监听是同步的,拿到回调后可以直接触发,避免使用真实定时器,例如:- test('should trigger onNetworkStatusChange when connection changes', () => { - return new Promise<void>(resolve => { + test('should trigger onNetworkStatusChange when connection changes', () => { + return new Promise<void>(resolve => { const cbList: any = {} // @ts-ignore navigator.connection = { effectiveType: '4g', addEventListener: vi.fn((ev, cb) => { cbList[ev] = cb }) } - - setTimeout(() => cbList.change(), 1000) - Taro.onNetworkStatusChange(ev => { expect(ev.isConnected).toBe(true) expect(ev.networkType).toBe('4g') resolve() }) + // onNetworkStatusChange 内部已同步注册 'change' 事件,这里直接触发即可 + cbList.change() }) })packages/taro-h5/__tests__/network/request.test.ts (1)
1-6: 全局 fetch mock 建议补充恢复逻辑,避免影响其他测试当前在模块顶层直接
const fetch = vi.fn(); global.fetch = fetch,每个用例里只做fetch.mockReset(),不会把global.fetch还原成原始实现。Vitest 默认是单进程共享测试环境,这样的全局替换有可能影响到其它文件中依赖真实fetch的用例。建议在顶部缓存原始实现,并在测试结束时恢复,例如:
-import { beforeEach, describe, expect, test, vi } from 'vitest' - -const fetch = vi.fn() -global.fetch = fetch +import { afterAll, beforeEach, describe, expect, test, vi } from 'vitest' + +const originalFetch = global.fetch as any +const fetch = vi.fn() +global.fetch = fetch + +afterAll(() => { + global.fetch = originalFetch +})这样既保留了当前文件的 mock 行为,又不会把 vi.fn() 泄漏到其它测试。
Also applies to: 8-21, 23-26
packages/taro-h5/__tests__/ui/interaction/modal.test.ts (1)
248-267: 两个基于 Promise 的异步 DOM 用例可以考虑统一为 async/await 写法(非必须)
should not show cancel button与should show another style when options.title is empty目前都通过手写return new Promise(resolve => { ... setTimeout(..., 200) })来驱动异步断言,逻辑上是正确的,测试也可以稳定结束。如果希望统一风格、便于后续维护,可以在合适的时候重构为 async/await 形式,例如:
- test('should not show cancel button', () => { - return new Promise<void>(resolve => { - Taro.showModal({ showCancel: false }) - ... - setTimeout(() => { - expect(cancel).not.toBeVisible() - expect(confirm).toBeTruthy() - resolve() - }, 200) - }) - }) + test('should not show cancel button', async () => { + Taro.showModal({ showCancel: false }) + ... + await new Promise(resolve => setTimeout(resolve, 200)) + expect(cancel).not.toBeVisible() + expect(confirm).toBeTruthy() + })当前实现本身没有明显缺陷,只是代码风格层面的建议,可以按需考虑。
Also applies to: 269-287
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (21)
packages/taro-api/package.json(1 hunks)packages/taro-h5/__mocks__/platform.ts(0 hunks)packages/taro-h5/__tests__/base/index.test.ts(1 hunks)packages/taro-h5/__tests__/base/network.test.ts(2 hunks)packages/taro-h5/__tests__/base/pxTransform.test.ts(1 hunks)packages/taro-h5/__tests__/base/system.test.ts(2 hunks)packages/taro-h5/__tests__/location/index.test.ts(4 hunks)packages/taro-h5/__tests__/network/request.test.ts(7 hunks)packages/taro-h5/__tests__/network/websocket.test.ts(5 hunks)packages/taro-h5/__tests__/storage/index.test.ts(9 hunks)packages/taro-h5/__tests__/ui/animation.test.ts(1 hunks)packages/taro-h5/__tests__/ui/interaction/actionSheet.test.ts(9 hunks)packages/taro-h5/__tests__/ui/interaction/loading.test.ts(2 hunks)packages/taro-h5/__tests__/ui/interaction/modal.test.ts(11 hunks)packages/taro-h5/__tests__/ui/interaction/toast.test.ts(3 hunks)packages/taro-h5/__tests__/ui/navigation.test.ts(4 hunks)packages/taro-h5/__tests__/ui/tab-bar.test.tsx(4 hunks)packages/taro-h5/__tests__/utils.ts(1 hunks)packages/taro-h5/__tests__/wxml/index.test.ts(3 hunks)packages/taro-h5/vitest.config.mts(1 hunks)packages/taro-runtime/package.json(1 hunks)
💤 Files with no reviewable changes (1)
- packages/taro-h5/mocks/platform.ts
🚧 Files skipped from review as they are similar to previous changes (6)
- packages/taro-h5/tests/ui/interaction/actionSheet.test.ts
- packages/taro-h5/tests/ui/interaction/toast.test.ts
- packages/taro-h5/tests/ui/interaction/loading.test.ts
- packages/taro-h5/tests/base/system.test.ts
- packages/taro-h5/tests/storage/index.test.ts
- packages/taro-h5/tests/base/index.test.ts
🧰 Additional context used
🧠 Learnings (8)
📓 Common learnings
Learnt from: ianzone
Repo: NervJS/taro PR: 18146
File: packages/babel-plugin-transform-react-jsx-to-rn-stylesheet/package.json:12-14
Timestamp: 2025-08-08T02:32:58.265Z
Learning: 在 Taro 项目的 pnpm 工作区中,Vitest 相关依赖(vitest 和 vitest/coverage-istanbul)被管理在根目录的 package.json 中,而不是各个子包的 devDependencies 中。这是 monorepo 中依赖提升的标准做法。
Learnt from: ianzone
Repo: NervJS/taro PR: 18646
File: packages/taro/package.json:40-40
Timestamp: 2025-11-21T07:15:22.634Z
Learning: 在 tarojs/taro 包中添加 vite 作为 devDependency 是为了让 tarojs/vite-runner 能够依赖正确的 vite 类型版本,确保 monorepo 中的类型兼容性。
Learnt from: ianzone
Repo: NervJS/taro PR: 18150
File: packages/babel-plugin-transform-taroapi/tests/__mocks__/h5-definition.json:2356-2356
Timestamp: 2025-08-25T22:16:50.118Z
Learning: The file `packages/babel-plugin-transform-taroapi/tests/__mocks__/h5-definition.json` is auto-generated by the post-build script `packages/taro-platform-h5/scripts/post-build.mjs`, which copies content from `taro-platform-h5/dist/definition.json`. This file should not be manually edited.
Learnt from: ianzone
Repo: NervJS/taro PR: 17842
File: packages/jest-helper/tsconfig.json:9-9
Timestamp: 2025-06-23T00:09:31.233Z
Learning: 在 jest-helper 包中,src 目录下没有 __tests__ 测试目录,只包含 resolver.ts、sequencer.ts 和 snapshot 目录。不要假设包中存在测试目录结构。
📚 Learning: 2025-08-25T22:16:50.118Z
Learnt from: ianzone
Repo: NervJS/taro PR: 18150
File: packages/babel-plugin-transform-taroapi/tests/__mocks__/h5-definition.json:2356-2356
Timestamp: 2025-08-25T22:16:50.118Z
Learning: The file `packages/babel-plugin-transform-taroapi/tests/__mocks__/h5-definition.json` is auto-generated by the post-build script `packages/taro-platform-h5/scripts/post-build.mjs`, which copies content from `taro-platform-h5/dist/definition.json`. This file should not be manually edited.
Applied to files:
packages/taro-h5/__tests__/ui/animation.test.tspackages/taro-api/package.jsonpackages/taro-h5/__tests__/base/pxTransform.test.tspackages/taro-h5/__tests__/wxml/index.test.tspackages/taro-h5/__tests__/ui/tab-bar.test.tsxpackages/taro-h5/__tests__/ui/interaction/modal.test.tspackages/taro-runtime/package.jsonpackages/taro-h5/__tests__/ui/navigation.test.tspackages/taro-h5/vitest.config.mtspackages/taro-h5/__tests__/utils.tspackages/taro-h5/__tests__/location/index.test.tspackages/taro-h5/__tests__/network/websocket.test.tspackages/taro-h5/__tests__/network/request.test.tspackages/taro-h5/__tests__/base/network.test.ts
📚 Learning: 2025-08-08T02:32:58.265Z
Learnt from: ianzone
Repo: NervJS/taro PR: 18146
File: packages/babel-plugin-transform-react-jsx-to-rn-stylesheet/package.json:12-14
Timestamp: 2025-08-08T02:32:58.265Z
Learning: 在 Taro 项目的 pnpm 工作区中,Vitest 相关依赖(vitest 和 vitest/coverage-istanbul)被管理在根目录的 package.json 中,而不是各个子包的 devDependencies 中。这是 monorepo 中依赖提升的标准做法。
Applied to files:
packages/taro-h5/__tests__/ui/animation.test.tspackages/taro-api/package.jsonpackages/taro-h5/__tests__/base/pxTransform.test.tspackages/taro-h5/__tests__/wxml/index.test.tspackages/taro-h5/__tests__/ui/tab-bar.test.tsxpackages/taro-h5/__tests__/ui/interaction/modal.test.tspackages/taro-runtime/package.jsonpackages/taro-h5/__tests__/ui/navigation.test.tspackages/taro-h5/vitest.config.mtspackages/taro-h5/__tests__/utils.tspackages/taro-h5/__tests__/location/index.test.tspackages/taro-h5/__tests__/network/websocket.test.tspackages/taro-h5/__tests__/network/request.test.tspackages/taro-h5/__tests__/base/network.test.ts
📚 Learning: 2025-05-25T18:02:31.387Z
Learnt from: ianzone
Repo: NervJS/taro PR: 17746
File: packages/taro-runtime/tsdown.config.ts:10-16
Timestamp: 2025-05-25T18:02:31.387Z
Learning: 在 taro-runtime 包的 tsdown 配置中,必须禁用 treeshake 来保留 dom-external/index.js 文件。
Applied to files:
packages/taro-api/package.jsonpackages/taro-h5/__tests__/wxml/index.test.tspackages/taro-runtime/package.jsonpackages/taro-h5/__tests__/utils.ts
📚 Learning: 2025-11-24T08:49:07.365Z
Learnt from: ianzone
Repo: NervJS/taro PR: 18649
File: packages/taroize/src/wxml.ts:731-731
Timestamp: 2025-11-24T08:49:07.365Z
Learning: 在 packages/taroize/src/wxml.ts 中,prettier.format() 返回值的 `as string` 类型断言是必要的,因为需要将结果重新赋值给类型为 `string | undefined` 的变量,而 prettier.format() 的返回类型可能是 `string | Promise<string>`,TypeScript 无法自动收窄类型。
Applied to files:
packages/taro-h5/__tests__/wxml/index.test.ts
📚 Learning: 2025-11-21T07:15:22.634Z
Learnt from: ianzone
Repo: NervJS/taro PR: 18646
File: packages/taro/package.json:40-40
Timestamp: 2025-11-21T07:15:22.634Z
Learning: 在 tarojs/taro 包中添加 vite 作为 devDependency 是为了让 tarojs/vite-runner 能够依赖正确的 vite 类型版本,确保 monorepo 中的类型兼容性。
Applied to files:
packages/taro-h5/__tests__/wxml/index.test.tspackages/taro-runtime/package.jsonpackages/taro-h5/vitest.config.mtspackages/taro-h5/__tests__/utils.ts
📚 Learning: 2025-06-23T00:09:31.233Z
Learnt from: ianzone
Repo: NervJS/taro PR: 17842
File: packages/jest-helper/tsconfig.json:9-9
Timestamp: 2025-06-23T00:09:31.233Z
Learning: 在 jest-helper 包中,src 目录下没有 __tests__ 测试目录,只包含 resolver.ts、sequencer.ts 和 snapshot 目录。不要假设包中存在测试目录结构。
Applied to files:
packages/taro-h5/__tests__/wxml/index.test.tspackages/taro-h5/__tests__/ui/navigation.test.tspackages/taro-h5/vitest.config.mtspackages/taro-h5/__tests__/utils.tspackages/taro-h5/__tests__/location/index.test.ts
📚 Learning: 2025-05-06T06:55:44.077Z
Learnt from: Single-Dancer
Repo: NervJS/taro PR: 17653
File: packages/taro-components-advanced/src/components/water-flow/node.ts:83-95
Timestamp: 2025-05-06T06:55:44.077Z
Learning: 在 Taro 的 getRectSizeSync 函数中,如果找不到指定的节点,函数会一直处于 pending 状态而不是抛出错误。在这种情况下,使用 try/catch 处理不够充分,需要添加超时处理如 Promise.race 来避免无限等待。
Applied to files:
packages/taro-h5/__tests__/wxml/index.test.ts
🧬 Code graph analysis (3)
packages/taro-h5/__tests__/ui/tab-bar.test.tsx (1)
packages/taro-h5/__tests__/utils.ts (1)
buildApp(65-79)
packages/taro-h5/__tests__/ui/navigation.test.ts (2)
packages/taro-h5/__tests__/utils.ts (1)
buildApp(65-79)packages/taro-router/src/router/navigation-bar.ts (1)
loadingElement(66-69)
packages/taro-h5/__tests__/network/request.test.ts (1)
packages/taro-plugin-http/src/runtime/XMLHttpRequest.ts (1)
err(316-344)
🪛 ast-grep (0.40.0)
packages/taro-h5/__tests__/wxml/index.test.ts
[warning] 34-34: Direct modification of innerHTML or outerHTML properties detected. Modifying these properties with unsanitized user input can lead to XSS vulnerabilities. Use safe alternatives or sanitize content first.
Context: pageDOM.innerHTML = '
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://owasp.org/www-community/xss-filter-evasion-cheatsheet
- https://cwe.mitre.org/data/definitions/79.html
(dom-content-modification)
[warning] 56-59: Direct modification of innerHTML or outerHTML properties detected. Modifying these properties with unsanitized user input can lead to XSS vulnerabilities. Use safe alternatives or sanitize content first.
Context: pageDOM.innerHTML = <div id="box__a" class="box" data-url="xyz">box1</div> <div id="box__b" class="box" data-url="xxx" data-key="uzi">box1</div>
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://owasp.org/www-community/xss-filter-evasion-cheatsheet
- https://cwe.mitre.org/data/definitions/79.html
(dom-content-modification)
[warning] 119-122: Direct modification of innerHTML or outerHTML properties detected. Modifying these properties with unsanitized user input can lead to XSS vulnerabilities. Use safe alternatives or sanitize content first.
Context: pageDOM.innerHTML = <div id="box__a" class="box" data-url="xyz">box1</div> <div id="box__b" class="box" data-url="xxx" data-key="uzi">box1</div>
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://owasp.org/www-community/xss-filter-evasion-cheatsheet
- https://cwe.mitre.org/data/definitions/79.html
(dom-content-modification)
[warning] 145-145: Direct modification of innerHTML or outerHTML properties detected. Modifying these properties with unsanitized user input can lead to XSS vulnerabilities. Use safe alternatives or sanitize content first.
Context: pageDOM.innerHTML = '
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://owasp.org/www-community/xss-filter-evasion-cheatsheet
- https://cwe.mitre.org/data/definitions/79.html
(dom-content-modification)
[warning] 173-176: Direct modification of innerHTML or outerHTML properties detected. Modifying these properties with unsanitized user input can lead to XSS vulnerabilities. Use safe alternatives or sanitize content first.
Context: pageDOM.innerHTML = <div id="box__a" class="box" data-url="xyz">box1</div> <div id="box__b" class="box" data-url="xxx" data-key="uzi">box1</div>
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://owasp.org/www-community/xss-filter-evasion-cheatsheet
- https://cwe.mitre.org/data/definitions/79.html
(dom-content-modification)
[warning] 34-34: Direct HTML content assignment detected. Modifying innerHTML, outerHTML, or using document.write with unsanitized content can lead to XSS vulnerabilities. Use secure alternatives like textContent or sanitize HTML with libraries like DOMPurify.
Context: pageDOM.innerHTML = '
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://www.dhairyashah.dev/posts/why-innerhtml-is-a-bad-idea-and-how-to-avoid-it/
- https://cwe.mitre.org/data/definitions/79.html
(unsafe-html-content-assignment)
[warning] 56-59: Direct HTML content assignment detected. Modifying innerHTML, outerHTML, or using document.write with unsanitized content can lead to XSS vulnerabilities. Use secure alternatives like textContent or sanitize HTML with libraries like DOMPurify.
Context: pageDOM.innerHTML = <div id="box__a" class="box" data-url="xyz">box1</div> <div id="box__b" class="box" data-url="xxx" data-key="uzi">box1</div>
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://www.dhairyashah.dev/posts/why-innerhtml-is-a-bad-idea-and-how-to-avoid-it/
- https://cwe.mitre.org/data/definitions/79.html
(unsafe-html-content-assignment)
[warning] 119-122: Direct HTML content assignment detected. Modifying innerHTML, outerHTML, or using document.write with unsanitized content can lead to XSS vulnerabilities. Use secure alternatives like textContent or sanitize HTML with libraries like DOMPurify.
Context: pageDOM.innerHTML = <div id="box__a" class="box" data-url="xyz">box1</div> <div id="box__b" class="box" data-url="xxx" data-key="uzi">box1</div>
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://www.dhairyashah.dev/posts/why-innerhtml-is-a-bad-idea-and-how-to-avoid-it/
- https://cwe.mitre.org/data/definitions/79.html
(unsafe-html-content-assignment)
[warning] 145-145: Direct HTML content assignment detected. Modifying innerHTML, outerHTML, or using document.write with unsanitized content can lead to XSS vulnerabilities. Use secure alternatives like textContent or sanitize HTML with libraries like DOMPurify.
Context: pageDOM.innerHTML = '
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://www.dhairyashah.dev/posts/why-innerhtml-is-a-bad-idea-and-how-to-avoid-it/
- https://cwe.mitre.org/data/definitions/79.html
(unsafe-html-content-assignment)
[warning] 173-176: Direct HTML content assignment detected. Modifying innerHTML, outerHTML, or using document.write with unsanitized content can lead to XSS vulnerabilities. Use secure alternatives like textContent or sanitize HTML with libraries like DOMPurify.
Context: pageDOM.innerHTML = <div id="box__a" class="box" data-url="xyz">box1</div> <div id="box__b" class="box" data-url="xxx" data-key="uzi">box1</div>
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://www.dhairyashah.dev/posts/why-innerhtml-is-a-bad-idea-and-how-to-avoid-it/
- https://cwe.mitre.org/data/definitions/79.html
(unsafe-html-content-assignment)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: Build Rust Binding / stable - x86_64-pc-windows-msvc
- GitHub Check: Build Rust Binding / stable - x86_64-apple-darwin
- GitHub Check: Build Rust Binding / stable - x86_64-unknown-linux-musl
- GitHub Check: Build Rust Binding / stable - aarch64-apple-darwin
- GitHub Check: Build Rust Binding / stable - x86_64-unknown-linux-gnu
- GitHub Check: Build Rust WASM / stable - wasm32-wasi
🔇 Additional comments (11)
packages/taro-h5/__tests__/ui/animation.test.ts (1)
1-3: Vitest 迁移与导入路径看起来正确这里改为从
vitest显式导入describe/it/expect,并从../../src/index引入Taro,对现有测试逻辑无行为改动,符合本 PR 的 Vitest 迁移思路,也不需要在子包单独新增 Vitest 依赖。
Based on learnings.packages/taro-h5/__tests__/base/pxTransform.test.ts (1)
1-5: Vitest 导入与本地源码引用方式合理
- 从
vitest显式导入describe/expect/test符合 Vitest 用法,也有利于类型推断。- 将
Taro引用从包名切换为../../src/index,能直接对源码进行测试,配合本 PR 的 Vitest 迁移目标是合理的;相对路径从__tests__/base回到包根再进src/index也正确。describe('pxTransform')的命名与 API 更加一致,没有行为变化。这段改动整体可以通过。
packages/taro-h5/__tests__/wxml/index.test.ts (1)
2-209: selectorQuery 用例 Promise 化改造合理,innerHTML 的安全告警在测试场景下可忽略这里将所有 selectorQuery 相关用例改为返回
Promise<void>,并在boundingClientRect/scrollOffset/fields/exec回调中调用resolve(),可以确保 Vitest 正确感知异步结束;beforeEach中重建Current.page和pageDOM也保持了原有语义。静态分析提示的pageDOM.innerHTML = ...相关 XSS 风险在本文件中仅用于构造测试 DOM,内容是写死的字符串,不来源于用户输入,实际并不存在安全问题,可以视为误报。packages/taro-h5/vitest.config.mts (1)
1-18: taro-h5 的 Vitest 配置与现有测试结构匹配良好
environment: 'jsdom'、include: ['__tests__/**/*.test.ts?(x)']、setupFiles: ['__mocks__/setEnv.ts']以及将@tarojs/taroalias 到本包src/index.ts的配置都与当前测试文件的组织方式和导入路径相吻合,覆盖范围限定在src/**/*.ts也比较合理。建议在本分支实际跑一次vitest/CI 确认别名和 setup 文件路径在不同平台上都能正常解析即可。packages/taro-h5/__tests__/location/index.test.ts (1)
1-112: location 相关用例迁移到 vi.fn/spy 的方式清晰且语义等价
navigator.geolocation.getCurrentPosition与window.wx.getLocation都改为vi.fn,并在afterEach中统一vi.restoreAllMocks(),配合对window.wx的 finally 删除,能很好地隔离各测试间的副作用;success/fail/complete回调的断言逻辑与原先一致。整体迁移到本地../../src/index的 Taro 实现后,行为保持不变,看不到明显问题。packages/taro-api/package.json (1)
11-16: Verify deep import usage in @tarojs/api before restricting exportsAdding an
"exports"field with only the"."entry will prevent deep imports like@tarojs/api/dist/...at runtime. Before merging, confirm that neither internal code nor downstream consumers depend on such deep import paths. If they do, either extend the exports configuration to support them or update all references.packages/taro-h5/__tests__/network/request.test.ts (2)
8-21: fetch 辅助 mock 与回调 vi.fn 迁移整体语义正确
mockFetchOnce/mockFetchReject对典型成功和失败场景封装得比较清晰,ok/status/statusText与 JSON 解析逻辑都符合预期;各处success/fail/complete从jest.fn迁移到vi.fn也是 1:1 替换,没有引入行为变化。这些用例覆盖了:
- 普通返回、字符串 URL 参数写入、POST 参数与 header、201/400 状态码解析;
- 异常场景下 error 对象透传与回调触发次数。
整体看迁移是安全的,这一段无需额外修改。
Also applies to: 29-31, 33-33, 60-60, 73-73, 111-116, 134-139
160-183: 超时中止用例的 AbortSignal/DOMException 模拟方式合理
fetch.mockImplementationOnce中对options.signal的处理细节比较到位:
- 先判断
signal.aborted,已中止时立即reject(new DOMException('The operation was aborted.', 'AbortError'));- 否则监听
abort事件,在触发时同样以 DOMException 拒绝;- 不被中止的情况下,延时 3 秒返回正常响应。
配合
timeout: 30的请求参数,可以很好地验证Taro.request的超时中止逻辑;用例中断言code === 20、name === 'AbortError'和message文本也与标准 DOMException 表现一致。这段逻辑在 Vitest 环境下是可预期且健壮的。Also applies to: 186-201
packages/taro-h5/__tests__/ui/interaction/modal.test.ts (1)
1-3: modal 参数校验与基础交互用例的 Vitest 迁移是等价的这里将所有
success/fail/complete替换为vi.fn(),其余断言逻辑(错误文案、回调调用次数和参数)保持不变,basic test/ “cancel 为 true” 等用例的行为与原 Jest 版本一致。结合
@testing-library/jest-dom/vitest提供的 matcher,像toBeVisible、toHaveStyle、toHaveTextContent等断言在 Vitest 下也是兼容的,当前改动没有发现语义偏差或潜在问题。Also applies to: 7-9, 24-27, 41-43, 58-60, 75-77, 92-94, 109-111, 126-128, 147-149, 196-198
packages/taro-h5/__tests__/network/websocket.test.ts (2)
1-4: WebSocket 全局 mock 的搭建与恢复方式合理这里通过:
- 在
describe作用域捕获const originalWebSocket = globalThis.WebSocket;beforeEach中覆盖globalThis.WebSocket和window.WebSocket为mock-socket的WebSocket;afterEach中恢复为originalWebSocket并vi.restoreAllMocks()清理 console spy,基本保证了:
- 用例执行期间始终使用 mock WebSocket;
- 不会把 mock-socket 的实现泄漏到其它测试文件;
- console 日志不会干扰测试输出,但仍可被断言。
整体 setup/teardown 设计是正确、健壮的。
Also applies to: 7-23
35-39: WebSocket 相关行为用例迁移到 Vitest 后语义保持一致几个核心用例的改动都比较到位:
- 参数校验(options 非对象、url 不是 string 或不以 ws(s) 开头)里回调改为
vi.fn(),仍然通过expect.assertions保证断言数量,并校验fail/complete的入参;- “最多 5 个连接”用例通过
Promise.all建立 5 个连接,再尝试第 6 个,沿用errMsg文案和回调次数校验,同时在最后显式tasks.forEach(task => task.close())做清理;- “should work basically” 使用
mock-socket的Server,配合onOpen/onMessage/onClose回调和expect.assertions(11),覆盖连接、收发消息、主动关闭等完整链路;- “发送已关闭连接抛错” 用例中先
task.close()再调用send,通过断言console.error、success/fail/complete的调用情况验证错误分支。这些场景下从 Jest 到 Vitest 的替换(
jest.fn→vi.fn、jest.spyOn→vi.spyOn等)是等价的,异步部分也都通过返回 Promise 或使用expect.assertions做了收口,目前看逻辑正确、可维护性良好。Also applies to: 60-63, 82-113, 116-173, 191-201, 210-214
Codecov Report✅ All modified and coverable lines are covered by tests. ❌ Your project check has failed because the head coverage (50.71%) is below the target coverage (75.00%). You can increase the head coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## main #18668 +/- ##
==========================================
- Coverage 52.63% 50.71% -1.93%
==========================================
Files 463 244 -219
Lines 25108 11258 -13850
Branches 6629 2703 -3926
==========================================
- Hits 13215 5709 -7506
+ Misses 9726 4407 -5319
+ Partials 2167 1142 -1025
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
这个 PR 做了什么? (简要描述所做更改)
这个 PR 是什么类型? (至少选择一个)
这个 PR 涉及以下平台:
Summary by CodeRabbit
Chores(杂项)
Tests(测试)
✏️ Tip: You can customize this high-level summary in your review settings.