Use full Chrome for interactive Reddit login
This commit is contained in:
1 parent
70d62b2da3
commit
674cd89cd7
5 files changed
+241
-3
No files matched your search
@@ -0,0 +1,90 @@
|
||||
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');
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user