Skip to content

Commit 94a960c

Browse files
Add unit tests for the browserless function in the web crawler module.
1 parent 5fdb3a2 commit 94a960c

File tree

1 file changed

+129
-0
lines changed

1 file changed

+129
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
import { describe, expect, it, vi } from 'vitest';
2+
3+
import { browserless } from '../browserless';
4+
5+
describe('browserless', () => {
6+
const mockFetch = vi.fn();
7+
global.fetch = mockFetch;
8+
9+
const mockEnv = {
10+
BROWSERLESS_TOKEN: 'test-token',
11+
BROWSERLESS_URL: 'http://test-url',
12+
} as any;
13+
14+
beforeEach(() => {
15+
vi.resetModules();
16+
vi.resetAllMocks();
17+
process.env = { ...mockEnv };
18+
});
19+
20+
it('should throw BrowserlessInitError when missing required env vars', async () => {
21+
process.env = {} as any;
22+
await expect(browserless('http://test.com', { filterOptions: {} })).rejects.toThrow(
23+
'`BROWSERLESS_URL` or `BROWSERLESS_TOKEN` are required',
24+
);
25+
});
26+
27+
it('should return undefined when fetch fails', async () => {
28+
mockFetch.mockRejectedValueOnce(new Error('Fetch failed'));
29+
30+
const result = await browserless('http://test.com', { filterOptions: {} });
31+
32+
expect(result).toBeUndefined();
33+
});
34+
35+
it('should return undefined when content is empty', async () => {
36+
mockFetch.mockResolvedValueOnce({
37+
text: () => Promise.resolve('<html></html>'),
38+
});
39+
40+
const result = await browserless('http://test.com', { filterOptions: {} });
41+
42+
expect(result).toBeUndefined();
43+
});
44+
45+
it('should return undefined when title is "Just a moment..."', async () => {
46+
mockFetch.mockResolvedValueOnce({
47+
text: () =>
48+
Promise.resolve(
49+
'<html><head><title>Just a moment...</title></head><body>content</body></html>',
50+
),
51+
});
52+
53+
const result = await browserless('http://test.com', { filterOptions: {} });
54+
55+
expect(result).toBeUndefined();
56+
});
57+
58+
it('should return crawl result when successful', async () => {
59+
mockFetch.mockResolvedValueOnce({
60+
text: () =>
61+
Promise.resolve(
62+
'<html><head><title>Test Title</title><meta name="description" content="Test content"></head><body><p>Test content</p></body></html>',
63+
),
64+
});
65+
66+
const result = await browserless('http://test.com', { filterOptions: {} });
67+
68+
expect(result).toEqual({
69+
content: expect.any(String),
70+
contentType: 'text',
71+
description: 'Test content',
72+
length: expect.any(Number),
73+
siteName: undefined,
74+
title: 'Test Title',
75+
url: 'http://test.com',
76+
});
77+
});
78+
79+
it('should make request with correct parameters', async () => {
80+
process.env = {
81+
BROWSERLESS_TOKEN: 'test-token',
82+
} as any;
83+
84+
mockFetch.mockResolvedValueOnce({
85+
text: () =>
86+
Promise.resolve(
87+
'<html><head><title>Test Title</title></head><body><p>Test content</p></body></html>',
88+
),
89+
});
90+
91+
await browserless('http://test.com', { filterOptions: {} });
92+
93+
expect(mockFetch).toHaveBeenCalledWith('https://chrome.browserless.io/content', {
94+
body: JSON.stringify({
95+
gotoOptions: { waitUntil: 'networkidle2' },
96+
url: 'http://test.com',
97+
}),
98+
headers: {
99+
'Content-Type': 'application/json',
100+
},
101+
method: 'POST',
102+
});
103+
});
104+
105+
it('should use default browserless URL when BROWSERLESS_URL is not set', async () => {
106+
const { BROWSERLESS_URL, ...envWithoutUrl } = mockEnv;
107+
process.env = { ...envWithoutUrl };
108+
109+
mockFetch.mockResolvedValueOnce({
110+
text: () =>
111+
Promise.resolve(
112+
'<html><head><title>Test Title</title></head><body><p>Test content</p></body></html>',
113+
),
114+
});
115+
116+
await browserless('http://test.com', { filterOptions: {} });
117+
118+
expect(mockFetch).toHaveBeenCalledWith('https://chrome.browserless.io/content', {
119+
body: JSON.stringify({
120+
gotoOptions: { waitUntil: 'networkidle2' },
121+
url: 'http://test.com',
122+
}),
123+
headers: {
124+
'Content-Type': 'application/json',
125+
},
126+
method: 'POST',
127+
});
128+
});
129+
});

0 commit comments

Comments
 (0)