;
+ text: string;
+ children: HtmlNode[];
+}
+
+export interface HtmlTreeResult {
+ selector: string | null;
+ matched: number;
+ tree: HtmlNode | null;
+}
diff --git a/src/cli.test.ts b/src/cli.test.ts
index eb188c653..cd552aa92 100644
--- a/src/cli.test.ts
+++ b/src/cli.test.ts
@@ -442,6 +442,166 @@ describe('browser network command', () => {
});
});
+describe('browser get html command', () => {
+ const consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
+
+ function lastLogArg(): unknown {
+ const calls = consoleLogSpy.mock.calls;
+ if (calls.length === 0) throw new Error('expected console.log call');
+ return calls[calls.length - 1][0];
+ }
+ function lastJsonLog(): any {
+ const arg = lastLogArg();
+ if (typeof arg !== 'string') throw new Error(`expected string arg, got ${typeof arg}`);
+ return JSON.parse(arg);
+ }
+
+ beforeEach(() => {
+ process.exitCode = undefined;
+ process.env.OPENCLI_CACHE_DIR = fs.mkdtempSync(path.join(os.tmpdir(), 'opencli-html-'));
+ consoleLogSpy.mockClear();
+ mockBrowserConnect.mockClear();
+ mockBrowserClose.mockReset().mockResolvedValue(undefined);
+
+ browserState.page = {
+ setActivePage: vi.fn(),
+ getActivePage: vi.fn().mockReturnValue('tab-1'),
+ tabs: vi.fn().mockResolvedValue([{ page: 'tab-1', active: true }]),
+ evaluate: vi.fn(),
+ } as unknown as IPage;
+ });
+
+ it('returns full outerHTML by default with no truncation', async () => {
+ const big = '' + 'x'.repeat(100_000) + '
';
+ (browserState.page!.evaluate as any).mockResolvedValueOnce({ kind: 'ok', html: big });
+ const program = createProgram('', '');
+
+ await program.parseAsync(['node', 'opencli', 'browser', 'get', 'html']);
+
+ expect(lastLogArg()).toBe(big);
+ });
+
+ it('caps output with --max and prepends a visible truncation marker', async () => {
+ const big = '' + 'x'.repeat(500) + '
';
+ (browserState.page!.evaluate as any).mockResolvedValueOnce({ kind: 'ok', html: big });
+ const program = createProgram('', '');
+
+ await program.parseAsync(['node', 'opencli', 'browser', 'get', 'html', '--max', '100']);
+
+ const out = String(lastLogArg());
+ expect(out.startsWith('\n${html.slice(0, max)}`);
+ return;
+ }
+ console.log(html);
}));
addBrowserTabOption(get.command('attributes').argument('', 'Element index').description('Element attributes'))