@jackwener/opencli 1.7.3 → 1.7.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +81 -59
- package/README.zh-CN.md +93 -67
- package/cli-manifest.json +5015 -2975
- package/clis/antigravity/serve.js +71 -25
- package/clis/baidu-scholar/search.js +87 -0
- package/clis/baidu-scholar/search.test.js +23 -0
- package/clis/bilibili/favorite.js +18 -13
- package/clis/binance/depth.js +3 -4
- package/clis/boss/utils.js +2 -3
- package/clis/chatgpt-app/ax.js +6 -3
- package/clis/deepseek/ask.js +74 -0
- package/clis/deepseek/history.js +25 -0
- package/clis/deepseek/new.js +20 -0
- package/clis/deepseek/read.js +22 -0
- package/clis/deepseek/status.js +24 -0
- package/clis/deepseek/utils.js +208 -0
- package/clis/douban/search.js +1 -0
- package/clis/douban/search.test.js +11 -0
- package/clis/douban/subject.js +20 -93
- package/clis/douban/subject.test.js +11 -0
- package/clis/douban/utils.js +250 -8
- package/clis/douban/utils.test.js +179 -4
- package/clis/doubao/utils.js +319 -130
- package/clis/doubao/utils.test.js +241 -2
- package/clis/eastmoney/_secid.js +78 -0
- package/clis/eastmoney/announcement.js +52 -0
- package/clis/eastmoney/convertible.js +73 -0
- package/clis/eastmoney/etf.js +65 -0
- package/clis/eastmoney/holders.js +78 -0
- package/clis/eastmoney/hot-rank.js +50 -0
- package/clis/eastmoney/hot-rank.test.js +59 -0
- package/clis/eastmoney/index-board.js +96 -0
- package/clis/eastmoney/kline.js +87 -0
- package/clis/eastmoney/kuaixun.js +54 -0
- package/clis/eastmoney/longhu.js +67 -0
- package/clis/eastmoney/money-flow.js +78 -0
- package/clis/eastmoney/northbound.js +57 -0
- package/clis/eastmoney/quote.js +107 -0
- package/clis/eastmoney/rank.js +94 -0
- package/clis/eastmoney/sectors.js +76 -0
- package/clis/google-scholar/search.js +58 -0
- package/clis/google-scholar/search.test.js +23 -0
- package/clis/gov-law/commands.test.js +39 -0
- package/clis/gov-law/recent.js +22 -0
- package/clis/gov-law/search.js +41 -0
- package/clis/gov-law/shared.js +51 -0
- package/clis/gov-policy/commands.test.js +27 -0
- package/clis/gov-policy/recent.js +47 -0
- package/clis/gov-policy/search.js +48 -0
- package/clis/grok/image.test.ts +107 -0
- package/clis/grok/image.ts +356 -0
- package/clis/nowcoder/companies.js +23 -0
- package/clis/nowcoder/creators.js +27 -0
- package/clis/nowcoder/detail.js +61 -0
- package/clis/nowcoder/experience.js +36 -0
- package/clis/nowcoder/hot.js +24 -0
- package/clis/nowcoder/jobs.js +21 -0
- package/clis/nowcoder/notifications.js +29 -0
- package/clis/nowcoder/papers.js +40 -0
- package/clis/nowcoder/practice.js +37 -0
- package/clis/nowcoder/recommend.js +30 -0
- package/clis/nowcoder/referral.js +39 -0
- package/clis/nowcoder/salary.js +40 -0
- package/clis/nowcoder/search.js +49 -0
- package/clis/nowcoder/suggest.js +33 -0
- package/clis/nowcoder/topics.js +27 -0
- package/clis/nowcoder/trending.js +25 -0
- package/clis/tdx/hot-rank.js +47 -0
- package/clis/tdx/hot-rank.test.js +59 -0
- package/clis/ths/hot-rank.js +49 -0
- package/clis/ths/hot-rank.test.js +64 -0
- package/clis/twitter/bookmarks.js +2 -1
- package/clis/twitter/list-add.js +337 -0
- package/clis/twitter/list-add.test.js +15 -0
- package/clis/twitter/list-remove.js +297 -0
- package/clis/twitter/list-remove.test.js +14 -0
- package/clis/twitter/list-tweets.js +185 -0
- package/clis/twitter/list-tweets.test.js +108 -0
- package/clis/twitter/lists.js +134 -47
- package/clis/twitter/lists.test.js +105 -38
- package/clis/uiverse/_shared.js +368 -0
- package/clis/uiverse/_shared.test.js +55 -0
- package/clis/uiverse/code.js +47 -0
- package/clis/uiverse/preview.js +71 -0
- package/clis/wanfang/search.js +66 -0
- package/clis/wanfang/search.test.js +23 -0
- package/clis/web/read.js +1 -1
- package/clis/weixin/download.js +3 -2
- package/clis/xiaohongshu/comments.js +2 -2
- package/clis/xiaohongshu/comments.test.js +46 -25
- package/clis/xiaohongshu/download.js +6 -7
- package/clis/xiaohongshu/download.test.js +17 -5
- package/clis/xiaohongshu/note-helpers.js +46 -12
- package/clis/xiaohongshu/note.js +3 -5
- package/clis/xiaohongshu/note.test.js +52 -25
- package/clis/xiaohongshu/publish.js +149 -28
- package/clis/xiaohongshu/publish.test.js +319 -6
- package/clis/xiaoyuzhou/auth.js +303 -0
- package/clis/xiaoyuzhou/auth.test.js +124 -0
- package/clis/xiaoyuzhou/download.js +53 -0
- package/clis/xiaoyuzhou/download.test.js +135 -0
- package/clis/xiaoyuzhou/episode.js +9 -4
- package/clis/xiaoyuzhou/podcast-episodes.js +15 -11
- package/clis/xiaoyuzhou/podcast.js +9 -4
- package/clis/xiaoyuzhou/transcript.js +76 -0
- package/clis/xiaoyuzhou/transcript.test.js +195 -0
- package/clis/xiaoyuzhou/utils.js +0 -40
- package/clis/xiaoyuzhou/utils.test.js +15 -75
- package/clis/youtube/feed.js +120 -0
- package/clis/youtube/history.js +118 -0
- package/clis/youtube/like.js +62 -0
- package/clis/youtube/playlist.js +97 -0
- package/clis/youtube/subscribe.js +71 -0
- package/clis/youtube/subscriptions.js +57 -0
- package/clis/youtube/unlike.js +62 -0
- package/clis/youtube/unsubscribe.js +71 -0
- package/clis/youtube/utils.js +122 -0
- package/clis/youtube/utils.test.js +32 -1
- package/clis/youtube/watch-later.js +76 -0
- package/clis/zsxq/dynamics.js +1 -1
- package/clis/zsxq/utils.js +6 -3
- package/clis/zsxq/utils.test.js +31 -0
- package/dist/src/browser/base-page.d.ts +1 -1
- package/dist/src/browser/base-page.js +25 -5
- package/dist/src/browser/bridge.d.ts +3 -0
- package/dist/src/browser/bridge.js +52 -15
- package/dist/src/browser/cdp.js +2 -1
- package/dist/src/browser/daemon-client.d.ts +7 -4
- package/dist/src/browser/daemon-client.js +6 -1
- package/dist/src/browser/daemon-client.test.js +40 -1
- package/dist/src/browser/dom-snapshot.js +20 -3
- package/dist/src/browser/page.d.ts +18 -5
- package/dist/src/browser/page.js +96 -15
- package/dist/src/browser/page.test.js +158 -1
- package/dist/src/browser/target-errors.d.ts +23 -0
- package/dist/src/browser/target-errors.js +29 -0
- package/dist/src/browser/target-errors.test.js +61 -0
- package/dist/src/browser/target-resolver.d.ts +57 -0
- package/dist/src/browser/target-resolver.js +298 -0
- package/dist/src/browser/target-resolver.test.js +43 -0
- package/dist/src/browser.test.js +38 -1
- package/dist/src/cli.js +272 -187
- package/dist/src/cli.test.js +167 -90
- package/dist/src/commanderAdapter.d.ts +0 -1
- package/dist/src/commanderAdapter.js +2 -16
- package/dist/src/commanderAdapter.test.js +1 -1
- package/dist/src/commands/daemon.d.ts +4 -2
- package/dist/src/commands/daemon.js +22 -2
- package/dist/src/commands/daemon.test.js +65 -2
- package/dist/src/completion-shared.js +2 -5
- package/dist/src/daemon.js +10 -0
- package/dist/src/doctor.d.ts +1 -0
- package/dist/src/doctor.js +32 -9
- package/dist/src/doctor.test.js +28 -12
- package/dist/src/download/article-download.d.ts +1 -0
- package/dist/src/download/article-download.js +3 -0
- package/dist/src/download/article-download.test.js +39 -0
- package/dist/src/external-clis.yaml +2 -2
- package/dist/src/logger.d.ts +2 -2
- package/dist/src/logger.js +3 -3
- package/dist/src/output.js +1 -5
- package/dist/src/output.test.js +0 -21
- package/dist/src/pipeline/steps/transform.js +1 -1
- package/dist/src/pipeline/template.d.ts +1 -0
- package/dist/src/pipeline/template.js +11 -3
- package/dist/src/pipeline/template.test.js +3 -0
- package/dist/src/pipeline/transform.test.js +14 -0
- package/dist/src/plugin.d.ts +8 -9
- package/dist/src/plugin.js +24 -28
- package/dist/src/plugin.test.js +16 -60
- package/dist/src/registry.d.ts +1 -0
- package/dist/src/registry.js +3 -2
- package/dist/src/registry.test.js +22 -0
- package/dist/src/types.d.ts +15 -6
- package/package.json +1 -1
- package/clis/twitter/lists-parser.js +0 -77
- package/clis/twitter/lists.d.ts +0 -5
- package/dist/src/cascade.d.ts +0 -46
- package/dist/src/cascade.js +0 -135
- package/dist/src/explore.d.ts +0 -99
- package/dist/src/explore.js +0 -402
- package/dist/src/generate-verified.d.ts +0 -105
- package/dist/src/generate-verified.js +0 -696
- package/dist/src/generate-verified.test.js +0 -925
- package/dist/src/generate.d.ts +0 -46
- package/dist/src/generate.js +0 -117
- package/dist/src/record.d.ts +0 -96
- package/dist/src/record.js +0 -657
- package/dist/src/record.test.js +0 -293
- package/dist/src/skill-generate.d.ts +0 -30
- package/dist/src/skill-generate.js +0 -75
- package/dist/src/skill-generate.test.js +0 -173
- package/dist/src/synthesize.d.ts +0 -97
- package/dist/src/synthesize.js +0 -208
- /package/dist/src/{generate-verified.test.d.ts → browser/target-errors.test.d.ts} +0 -0
- /package/dist/src/{record.test.d.ts → browser/target-resolver.test.d.ts} +0 -0
- /package/dist/src/{skill-generate.test.d.ts → download/article-download.test.d.ts} +0 -0
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import vm from 'node:vm';
|
|
2
2
|
import { describe, expect, it, vi } from 'vitest';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
getDoubanPhotoExtension,
|
|
5
|
+
inferDoubanSearchResultType,
|
|
6
|
+
loadDoubanSubjectDetail,
|
|
7
|
+
loadDoubanSubjectPhotos,
|
|
8
|
+
normalizeDoubanBookSubject,
|
|
9
|
+
normalizeDoubanSubjectId,
|
|
10
|
+
promoteDoubanPhotoUrl,
|
|
11
|
+
resolveDoubanPhotoAssetUrl,
|
|
12
|
+
searchDouban,
|
|
13
|
+
} from './utils.js';
|
|
4
14
|
|
|
5
15
|
function createFakeNode(text = '', attrs = {}) {
|
|
6
16
|
return {
|
|
@@ -10,18 +20,22 @@ function createFakeNode(text = '', attrs = {}) {
|
|
|
10
20
|
},
|
|
11
21
|
};
|
|
12
22
|
}
|
|
23
|
+
|
|
13
24
|
function createFakeSearchItem({ title, url, rating, abstract, cover }) {
|
|
14
25
|
return {
|
|
15
26
|
querySelector(selector) {
|
|
16
|
-
if (selector === '.title-text, .title a, a[title]') {
|
|
27
|
+
if (selector === '.title-text, .title a, .title h3 a, h3 a, a[title]') {
|
|
17
28
|
return createFakeNode(title, { href: url, title });
|
|
18
29
|
}
|
|
19
30
|
if (selector === '.rating_nums') {
|
|
20
31
|
return createFakeNode(rating);
|
|
21
32
|
}
|
|
22
|
-
if (selector === '.meta.abstract, .meta, .abstract, p') {
|
|
33
|
+
if (selector === '.meta.abstract, .meta, .abstract, .subject-abstract, p') {
|
|
23
34
|
return createFakeNode(abstract);
|
|
24
35
|
}
|
|
36
|
+
if (selector === 'a[href*="/subject/"]') {
|
|
37
|
+
return createFakeNode('', { href: url });
|
|
38
|
+
}
|
|
25
39
|
if (selector === 'img') {
|
|
26
40
|
return createFakeNode('', { src: cover });
|
|
27
41
|
}
|
|
@@ -29,11 +43,15 @@ function createFakeSearchItem({ title, url, rating, abstract, cover }) {
|
|
|
29
43
|
},
|
|
30
44
|
};
|
|
31
45
|
}
|
|
46
|
+
|
|
32
47
|
async function runSearchEvaluate(script, rawItems, domItems) {
|
|
33
48
|
const document = {
|
|
34
49
|
querySelector(selector) {
|
|
35
50
|
if (selector === '.item-root .title-text, .item-root .title a') {
|
|
36
|
-
return domItems[0]?.querySelector('.title-text, .title a, a[title]') || null;
|
|
51
|
+
return domItems[0]?.querySelector('.title-text, .title a, .title h3 a, h3 a, a[title]') || null;
|
|
52
|
+
}
|
|
53
|
+
if (selector === '.item-root .title-text, .item-root .title a, .result-list .result-item h3 a') {
|
|
54
|
+
return domItems[0]?.querySelector('.title-text, .title a, .title h3 a, h3 a, a[title]') || null;
|
|
37
55
|
}
|
|
38
56
|
return null;
|
|
39
57
|
},
|
|
@@ -41,9 +59,13 @@ async function runSearchEvaluate(script, rawItems, domItems) {
|
|
|
41
59
|
if (selector === '.item-root') {
|
|
42
60
|
return domItems;
|
|
43
61
|
}
|
|
62
|
+
if (selector === '.item-root, .result-list .result-item') {
|
|
63
|
+
return domItems;
|
|
64
|
+
}
|
|
44
65
|
return [];
|
|
45
66
|
},
|
|
46
67
|
};
|
|
68
|
+
|
|
47
69
|
return vm.runInNewContext(script, {
|
|
48
70
|
Map,
|
|
49
71
|
Promise,
|
|
@@ -59,20 +81,25 @@ async function runSearchEvaluate(script, rawItems, domItems) {
|
|
|
59
81
|
},
|
|
60
82
|
});
|
|
61
83
|
}
|
|
84
|
+
|
|
62
85
|
describe('douban utils', () => {
|
|
63
86
|
it('normalizes valid subject ids', () => {
|
|
64
87
|
expect(normalizeDoubanSubjectId(' 30382501 ')).toBe('30382501');
|
|
65
88
|
});
|
|
89
|
+
|
|
66
90
|
it('rejects invalid subject ids', () => {
|
|
67
91
|
expect(() => normalizeDoubanSubjectId('tt30382501')).toThrow('Invalid Douban subject ID');
|
|
68
92
|
});
|
|
93
|
+
|
|
69
94
|
it('promotes thumbnail urls to large photo urls', () => {
|
|
70
95
|
expect(promoteDoubanPhotoUrl('https://img1.doubanio.com/view/photo/m/public/p2913450214.webp')).toBe('https://img1.doubanio.com/view/photo/l/public/p2913450214.webp');
|
|
71
96
|
expect(promoteDoubanPhotoUrl('https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2578474613.jpg')).toBe('https://img9.doubanio.com/view/photo/l/public/p2578474613.jpg');
|
|
72
97
|
});
|
|
98
|
+
|
|
73
99
|
it('rejects non-http photo urls during promotion', () => {
|
|
74
100
|
expect(promoteDoubanPhotoUrl('data:image/gif;base64,abc')).toBe('');
|
|
75
101
|
});
|
|
102
|
+
|
|
76
103
|
it('prefers lazy-loaded photo urls over data placeholders', () => {
|
|
77
104
|
expect(resolveDoubanPhotoAssetUrl([
|
|
78
105
|
'',
|
|
@@ -80,9 +107,11 @@ describe('douban utils', () => {
|
|
|
80
107
|
'data:image/gif;base64,abc',
|
|
81
108
|
], 'https://movie.douban.com/subject/30382501/photos?type=Rb')).toBe('https://img1.doubanio.com/view/photo/m/public/p2913450214.webp');
|
|
82
109
|
});
|
|
110
|
+
|
|
83
111
|
it('drops unsupported non-http photo urls when no real image url exists', () => {
|
|
84
112
|
expect(resolveDoubanPhotoAssetUrl(['data:image/gif;base64,abc', 'blob:https://movie.douban.com/example'], 'https://movie.douban.com/subject/30382501/photos?type=Rb')).toBe('');
|
|
85
113
|
});
|
|
114
|
+
|
|
86
115
|
it('removes the default photo cap when scanning for an exact photo id', async () => {
|
|
87
116
|
const evaluate = vi.fn()
|
|
88
117
|
.mockResolvedValueOnce({ blocked: false, title: 'Some Movie', href: 'https://movie.douban.com/subject/30382501/photos?type=Rb' })
|
|
@@ -116,10 +145,12 @@ describe('douban utils', () => {
|
|
|
116
145
|
expect(scanScript).toContain(`const limit = ${Number.MAX_SAFE_INTEGER};`);
|
|
117
146
|
expect(scanScript).toContain('for (let pageIndex = 0; photos.length < limit; pageIndex += 1)');
|
|
118
147
|
});
|
|
148
|
+
|
|
119
149
|
it('keeps image extensions when download urls contain query params', () => {
|
|
120
150
|
expect(getDoubanPhotoExtension('https://img1.doubanio.com/view/photo/l/public/p2913450214.webp?foo=1')).toBe('.webp');
|
|
121
151
|
expect(getDoubanPhotoExtension('https://img1.doubanio.com/view/photo/l/public/p2913450214.jpeg')).toBe('.jpeg');
|
|
122
152
|
});
|
|
153
|
+
|
|
123
154
|
it('maps tv series results to tvshow in searchDouban output', async () => {
|
|
124
155
|
const domItems = [
|
|
125
156
|
createFakeSearchItem({
|
|
@@ -161,7 +192,149 @@ describe('douban utils', () => {
|
|
|
161
192
|
{ id: '36289423', type: 'movie', title: '射雕英雄传:侠之大者 (2025)' },
|
|
162
193
|
]);
|
|
163
194
|
});
|
|
195
|
+
|
|
196
|
+
it('normalizes douban book subject raw data into structured fields', () => {
|
|
197
|
+
const normalized = normalizeDoubanBookSubject({
|
|
198
|
+
id: '2567698',
|
|
199
|
+
title: '小狗钱钱',
|
|
200
|
+
subtitle: '让孩子和家长共同成长的财商童话',
|
|
201
|
+
originalTitle: 'Ein Hund namens Money',
|
|
202
|
+
infoText: `
|
|
203
|
+
作者: [德] 博多·舍费尔
|
|
204
|
+
出版社: 南海出版公司
|
|
205
|
+
副标题: 让孩子和家长共同成长的财商童话
|
|
206
|
+
原作名: Ein Hund namens Money
|
|
207
|
+
译者: 王钟欣 / 余茜
|
|
208
|
+
出版年: 2014-1-1
|
|
209
|
+
页数: 208
|
|
210
|
+
定价: 26.00元
|
|
211
|
+
装帧: 平装
|
|
212
|
+
丛书: 新经典文库·爱心树童书
|
|
213
|
+
ISBN: 9787544270871
|
|
214
|
+
`,
|
|
215
|
+
rating: '8.9',
|
|
216
|
+
ratingCount: '12345',
|
|
217
|
+
summary: '理财启蒙故事',
|
|
218
|
+
cover: 'https://img9.doubanio.com/view/subject/l/public/s29618581.jpg',
|
|
219
|
+
url: 'https://book.douban.com/subject/2567698/',
|
|
220
|
+
});
|
|
221
|
+
expect(normalized).toMatchObject({
|
|
222
|
+
id: '2567698',
|
|
223
|
+
type: 'book',
|
|
224
|
+
title: '小狗钱钱',
|
|
225
|
+
subtitle: '让孩子和家长共同成长的财商童话',
|
|
226
|
+
originalTitle: 'Ein Hund namens Money',
|
|
227
|
+
authors: ['[德] 博多·舍费尔'],
|
|
228
|
+
translators: ['王钟欣', '余茜'],
|
|
229
|
+
publisher: '南海出版公司',
|
|
230
|
+
publishDate: '2014-1-1',
|
|
231
|
+
publishYear: '2014',
|
|
232
|
+
pageCount: 208,
|
|
233
|
+
binding: '平装',
|
|
234
|
+
price: '26.00元',
|
|
235
|
+
series: '新经典文库·爱心树童书',
|
|
236
|
+
isbn13: '9787544270871',
|
|
237
|
+
rating: 8.9,
|
|
238
|
+
ratingCount: 12345,
|
|
239
|
+
summary: '理财启蒙故事',
|
|
240
|
+
cover: 'https://img9.doubanio.com/view/subject/l/public/s29618581.jpg',
|
|
241
|
+
url: 'https://book.douban.com/subject/2567698/',
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
it('loads book subject details from book.douban.com when type=book', async () => {
|
|
246
|
+
const page = {
|
|
247
|
+
goto: vi.fn().mockResolvedValue(undefined),
|
|
248
|
+
wait: vi.fn().mockResolvedValue(undefined),
|
|
249
|
+
evaluate: vi.fn()
|
|
250
|
+
.mockResolvedValueOnce({ blocked: false, title: '小狗钱钱 (豆瓣)', href: 'https://book.douban.com/subject/2567698/' })
|
|
251
|
+
.mockResolvedValueOnce({
|
|
252
|
+
id: '2567698',
|
|
253
|
+
title: '小狗钱钱',
|
|
254
|
+
subtitle: '',
|
|
255
|
+
originalTitle: '',
|
|
256
|
+
infoText: `
|
|
257
|
+
作者: [德] 博多·舍费尔
|
|
258
|
+
出版社: 南海出版公司
|
|
259
|
+
出版年: 2014-1-1
|
|
260
|
+
ISBN: 9787544270871
|
|
261
|
+
`,
|
|
262
|
+
rating: '8.9',
|
|
263
|
+
ratingCount: '12345',
|
|
264
|
+
summary: '理财启蒙故事',
|
|
265
|
+
cover: 'https://img9.doubanio.com/view/subject/l/public/s29618581.jpg',
|
|
266
|
+
url: 'https://book.douban.com/subject/2567698/',
|
|
267
|
+
}),
|
|
268
|
+
};
|
|
269
|
+
const detail = await loadDoubanSubjectDetail(page, '2567698', 'book');
|
|
270
|
+
expect(page.goto).toHaveBeenCalledWith('https://book.douban.com/subject/2567698/', {
|
|
271
|
+
waitUntil: 'load',
|
|
272
|
+
settleMs: 1500,
|
|
273
|
+
});
|
|
274
|
+
expect(page.wait).toHaveBeenCalledWith({ selector: 'h1 span, #info', timeout: 8 });
|
|
275
|
+
expect(detail).toMatchObject({
|
|
276
|
+
id: '2567698',
|
|
277
|
+
type: 'book',
|
|
278
|
+
title: '小狗钱钱',
|
|
279
|
+
authors: ['[德] 博多·舍费尔'],
|
|
280
|
+
publisher: '南海出版公司',
|
|
281
|
+
isbn13: '9787544270871',
|
|
282
|
+
rating: 8.9,
|
|
283
|
+
ratingCount: 12345,
|
|
284
|
+
url: 'https://book.douban.com/subject/2567698/',
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
it('retries transient detached navigation errors when loading douban search results', async () => {
|
|
289
|
+
const page = {
|
|
290
|
+
goto: vi.fn()
|
|
291
|
+
.mockRejectedValueOnce(new Error('Detached while handling command'))
|
|
292
|
+
.mockResolvedValueOnce(undefined),
|
|
293
|
+
wait: vi.fn().mockResolvedValue(undefined),
|
|
294
|
+
evaluate: vi.fn()
|
|
295
|
+
.mockResolvedValueOnce({
|
|
296
|
+
blocked: false,
|
|
297
|
+
title: '经济学思维 - 豆瓣搜索',
|
|
298
|
+
href: 'https://search.douban.com/book/subject_search?search_text=%E7%BB%8F%E6%B5%8E%E5%AD%A6%E6%80%9D%E7%BB%B4&cat=1001',
|
|
299
|
+
})
|
|
300
|
+
.mockResolvedValueOnce([
|
|
301
|
+
{
|
|
302
|
+
rank: 1,
|
|
303
|
+
id: '26895402',
|
|
304
|
+
type: 'book',
|
|
305
|
+
title: '经济学思维',
|
|
306
|
+
rating: 7.9,
|
|
307
|
+
abstract: '李子畅 / 中信出版社 / 2016-7',
|
|
308
|
+
url: 'https://book.douban.com/subject/26895402/',
|
|
309
|
+
cover: 'https://img1.doubanio.com/view/subject/m/public/s29000000.jpg',
|
|
310
|
+
},
|
|
311
|
+
]),
|
|
312
|
+
};
|
|
313
|
+
const results = await searchDouban(page, 'book', '经济学思维', 3);
|
|
314
|
+
expect(page.goto).toHaveBeenNthCalledWith(1, 'https://search.douban.com/book/subject_search?search_text=%E7%BB%8F%E6%B5%8E%E5%AD%A6%E6%80%9D%E7%BB%B4&cat=1001', {
|
|
315
|
+
waitUntil: 'load',
|
|
316
|
+
settleMs: 1500,
|
|
317
|
+
});
|
|
318
|
+
expect(page.goto).toHaveBeenCalledTimes(2);
|
|
319
|
+
expect(page.wait).toHaveBeenCalledWith({
|
|
320
|
+
selector: '.item-root .title-text, .item-root .title a, .result-list .result-item h3 a',
|
|
321
|
+
timeout: 8,
|
|
322
|
+
});
|
|
323
|
+
expect(results).toEqual([
|
|
324
|
+
{
|
|
325
|
+
rank: 1,
|
|
326
|
+
id: '26895402',
|
|
327
|
+
type: 'book',
|
|
328
|
+
title: '经济学思维',
|
|
329
|
+
rating: 7.9,
|
|
330
|
+
abstract: '李子畅 / 中信出版社 / 2016-7',
|
|
331
|
+
url: 'https://book.douban.com/subject/26895402/',
|
|
332
|
+
cover: 'https://img1.doubanio.com/view/subject/m/public/s29000000.jpg',
|
|
333
|
+
},
|
|
334
|
+
]);
|
|
335
|
+
});
|
|
164
336
|
});
|
|
337
|
+
|
|
165
338
|
describe('inferDoubanSearchResultType', () => {
|
|
166
339
|
it('returns tvshow for movie search results marked as TV', () => {
|
|
167
340
|
expect(inferDoubanSearchResultType('movie', {
|
|
@@ -169,12 +342,14 @@ describe('inferDoubanSearchResultType', () => {
|
|
|
169
342
|
labels: [{ text: '剧集' }],
|
|
170
343
|
})).toBe('tvshow');
|
|
171
344
|
});
|
|
345
|
+
|
|
172
346
|
it('returns movie when a movie search result has no TV signal', () => {
|
|
173
347
|
expect(inferDoubanSearchResultType('movie', {
|
|
174
348
|
moreUrl: "onclick=\"moreurl(this,{is_tv:'0'})\"",
|
|
175
349
|
labels: [{ text: '可播放' }],
|
|
176
350
|
})).toBe('movie');
|
|
177
351
|
});
|
|
352
|
+
|
|
178
353
|
it('preserves non-movie search types', () => {
|
|
179
354
|
expect(inferDoubanSearchResultType('book', {
|
|
180
355
|
moreUrl: '',
|