91 lines
3.1 KiB
TypeScript
91 lines
3.1 KiB
TypeScript
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
import type { BrowserContext, Page } from 'playwright';
|
|
import {
|
|
BrowserClient,
|
|
type BrowserRuntime,
|
|
type ConnectedBrowser,
|
|
} from '../src/browser/client.js';
|
|
import type { Logger } from '../src/utils/logger.js';
|
|
import { getTestConfig } from './testUtils.js';
|
|
|
|
function createLogger(): Logger {
|
|
return {
|
|
info: vi.fn(),
|
|
warn: vi.fn(),
|
|
error: vi.fn(),
|
|
debug: vi.fn(),
|
|
} as unknown as Logger;
|
|
}
|
|
|
|
afterEach(() => {
|
|
delete process.env.CHROME_CDP_URL;
|
|
});
|
|
|
|
describe('BrowserClient external Chrome', () => {
|
|
it('attaches to independently launched Chrome before considering Playwright launch', async () => {
|
|
process.env.CHROME_CDP_URL = 'http://127.0.0.1:9222';
|
|
const context = { pages: () => [] } as unknown as BrowserContext;
|
|
const connectedBrowser = {
|
|
contexts: () => [context],
|
|
close: vi.fn(),
|
|
} as unknown as ConnectedBrowser;
|
|
const runtime: BrowserRuntime = {
|
|
connectOverCDP: vi.fn().mockResolvedValue(connectedBrowser),
|
|
launchPersistentContext: vi.fn(),
|
|
};
|
|
|
|
const client = new BrowserClient(getTestConfig(), createLogger(), runtime);
|
|
const result = await client.initialize();
|
|
|
|
expect(result).toBe(context);
|
|
expect(runtime.connectOverCDP).toHaveBeenCalledWith('http://127.0.0.1:9222');
|
|
expect(runtime.launchPersistentContext).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('falls back to Playwright only when external Chrome cannot be reached', async () => {
|
|
process.env.CHROME_CDP_URL = 'http://127.0.0.1:9222';
|
|
const fallbackContext = { pages: () => [] } as unknown as BrowserContext;
|
|
const runtime: BrowserRuntime = {
|
|
connectOverCDP: vi.fn().mockRejectedValue(new Error('connection refused')),
|
|
launchPersistentContext: vi.fn().mockResolvedValue(fallbackContext),
|
|
};
|
|
|
|
const client = new BrowserClient(getTestConfig(), createLogger(), runtime);
|
|
const result = await client.initialize();
|
|
|
|
expect(result).toBe(fallbackContext);
|
|
expect(runtime.launchPersistentContext).toHaveBeenCalledOnce();
|
|
});
|
|
|
|
it('opens the login page for a human without submitting credentials', async () => {
|
|
process.env.CHROME_CDP_URL = 'http://127.0.0.1:9222';
|
|
const page = {
|
|
goto: vi.fn().mockResolvedValue(undefined),
|
|
bringToFront: vi.fn().mockResolvedValue(undefined),
|
|
fill: vi.fn(),
|
|
} as unknown as Page;
|
|
const context = { pages: () => [page] } as unknown as BrowserContext;
|
|
const runtime: BrowserRuntime = {
|
|
connectOverCDP: vi.fn().mockResolvedValue({
|
|
contexts: () => [context],
|
|
close: vi.fn(),
|
|
}),
|
|
launchPersistentContext: vi.fn(),
|
|
};
|
|
|
|
const client = new BrowserClient(getTestConfig({
|
|
reddit: { username: 'human', password: 'secret' },
|
|
}), createLogger(), runtime);
|
|
await client.initialize();
|
|
|
|
await expect(client.login()).resolves.toBe(false);
|
|
expect(page.bringToFront).toHaveBeenCalledOnce();
|
|
expect(page.goto).toHaveBeenCalledWith(
|
|
'https://www.reddit.com/login',
|
|
{ waitUntil: 'domcontentloaded' },
|
|
);
|
|
expect(page.fill).not.toHaveBeenCalled();
|
|
expect(client.getSessionState()).toBe('login-required');
|
|
});
|
|
});
|