From 572d6fc03db986f51c2754de623d35a992751215 Mon Sep 17 00:00:00 2001 From: Wolfgang Beyer Date: Wed, 13 May 2026 15:04:53 +0000 Subject: [PATCH 1/3] investigate --- src/tools/performance.ts | 2 + src/trace-processing/parse.ts | 6 + tests/e2e/chrome-devtools-commands.test.ts | 157 ++++++++++++--------- tests/tools/performance.test.ts | 4 + 4 files changed, 102 insertions(+), 67 deletions(-) diff --git a/src/tools/performance.ts b/src/tools/performance.ts index 39f9b3186..05fc7b44e 100644 --- a/src/tools/performance.ts +++ b/src/tools/performance.ts @@ -90,9 +90,11 @@ export const startTrace = definePageTool({ 'v8.execute', 'v8', ]; + await page.pptrPage.emulateCPUThrottling(20); await page.pptrPage.tracing.start({ categories, }); + // await context.restoreEmulation(page); if (request.params.reload) { await page.pptrPage.goto(pageUrlForTracing, { diff --git a/src/trace-processing/parse.ts b/src/trace-processing/parse.ts index 7b152d853..d1da581f2 100644 --- a/src/trace-processing/parse.ts +++ b/src/trace-processing/parse.ts @@ -76,9 +76,15 @@ ${DevTools.PerformanceTraceFormatter.callFrameDataFormatDescription} ${DevTools.PerformanceTraceFormatter.networkDataFormatDescription}`; +// here export function getTraceSummary(result: TraceResult): string { const focus = DevTools.AgentFocus.fromParsedTrace(result.parsedTrace); const formatter = new DevTools.PerformanceTraceFormatter(focus); + logger( + 'METADATA', + focus.parsedTrace.metadata, + JSON.stringify(focus.parsedTrace.metadata), + ); const summaryText = formatter.formatTraceSummary(); return `## Summary of Performance trace findings: ${summaryText} diff --git a/tests/e2e/chrome-devtools-commands.test.ts b/tests/e2e/chrome-devtools-commands.test.ts index 4884d4f82..30b8e65ab 100644 --- a/tests/e2e/chrome-devtools-commands.test.ts +++ b/tests/e2e/chrome-devtools-commands.test.ts @@ -8,11 +8,7 @@ import assert from 'node:assert'; import crypto from 'node:crypto'; import {describe, it, afterEach, beforeEach} from 'node:test'; -import { - assertDaemonIsNotRunning, - assertDaemonIsRunning, - runCli, -} from '../utils.js'; +import {assertDaemonIsNotRunning, runCli} from '../utils.js'; describe('chrome-devtools', () => { let sessionId: string; @@ -28,82 +24,109 @@ describe('chrome-devtools', () => { await assertDaemonIsNotRunning(sessionId); }); - it('can invoke list_pages', async () => { - await assertDaemonIsNotRunning(sessionId); - - const startResult = await runCli(['start'], sessionId); - assert.strictEqual( - startResult.status, - 0, - `start command failed: ${startResult.stderr}`, - ); - - const listPagesResult = await runCli(['list_pages'], sessionId); - assert.strictEqual( - listPagesResult.status, - 0, - `list_pages command failed: ${listPagesResult.stderr}`, + // it('can invoke list_pages', async () => { + // await assertDaemonIsNotRunning(sessionId); + + // const startResult = await runCli(['start'], sessionId); + // assert.strictEqual( + // startResult.status, + // 0, + // `start command failed: ${startResult.stderr}`, + // ); + + // const listPagesResult = await runCli(['list_pages'], sessionId); + // assert.strictEqual( + // listPagesResult.status, + // 0, + // `list_pages command failed: ${listPagesResult.stderr}`, + // ); + // assert( + // listPagesResult.stdout.includes('about:blank'), + // 'list_pages output is unexpected', + // ); + + // await assertDaemonIsRunning(sessionId); + // }); + + // it('can take screenshot', async () => { + // const startResult = await runCli(['start'], sessionId); + // assert.strictEqual( + // startResult.status, + // 0, + // `start command failed: ${startResult.stderr}`, + // ); + + // const result = await runCli(['take_screenshot'], sessionId); + // assert.strictEqual( + // result.status, + // 0, + // `take_screenshot command failed: ${result.stderr}`, + // ); + // assert( + // result.stdout.includes('.png'), + // 'take_screenshot output is unexpected', + // ); + // }); + + // it('fails to invoke list_network_requests when categoryNetwork is disabled', async () => { + // await runCli(['start', '--categoryNetwork=false'], sessionId); + + // const result = await runCli(['list_network_requests'], sessionId); + // assert.strictEqual(result.status, 0); + + // assert( + // result.stdout.includes( + // 'Tool list_network_requests is in category Network which is currently disabled', + // ), + // 'error message is unexpected: ' + result.stdout, + // ); + // assert( + // result.stdout.includes('chrome-devtools start --categoryNetwork=true'), + // 'restart command suggestion is missing: ' + result.stdout, + // ); + // }); + + // it('fails to invoke click_at when experimentalVision is disabled (default)', async () => { + // await runCli(['start'], sessionId); + + // const result = await runCli(['click_at', '100', '100'], sessionId); + // assert.strictEqual(result.status, 0); + // assert( + // result.stdout.includes( + // 'Tool click_at requires experimental feature --experimentalVision and is currently disabled', + // ), + // 'error message is unexpected: ' + result.stdout, + // ); + // assert( + // result.stdout.includes('chrome-devtools start --experimentalVision=true'), + // 'restart command suggestion is miss: ' + result.stdout, + // ); + // }); + + it('can record a performance trace', async () => { + const startResult = await runCli( + ['start', '--performanceCrux=false'], + sessionId, ); - assert( - listPagesResult.stdout.includes('about:blank'), - 'list_pages output is unexpected', - ); - - await assertDaemonIsRunning(sessionId); - }); - - it('can take screenshot', async () => { - const startResult = await runCli(['start'], sessionId); assert.strictEqual( startResult.status, 0, `start command failed: ${startResult.stderr}`, ); - const result = await runCli(['take_screenshot'], sessionId); + const result = await runCli(['performance_start_trace'], sessionId); assert.strictEqual( result.status, 0, - `take_screenshot command failed: ${result.stderr}`, - ); - assert( - result.stdout.includes('.png'), - 'take_screenshot output is unexpected', - ); - }); - - it('fails to invoke list_network_requests when categoryNetwork is disabled', async () => { - await runCli(['start', '--categoryNetwork=false'], sessionId); - - const result = await runCli(['list_network_requests'], sessionId); - assert.strictEqual(result.status, 0); - - assert( - result.stdout.includes( - 'Tool list_network_requests is in category Network which is currently disabled', - ), - 'error message is unexpected: ' + result.stdout, - ); - assert( - result.stdout.includes('chrome-devtools start --categoryNetwork=true'), - 'restart command suggestion is missing: ' + result.stdout, + `performance_start_trace command failed: ${result.stderr}`, ); - }); - - it('fails to invoke click_at when experimentalVision is disabled (default)', async () => { - await runCli(['start'], sessionId); - - const result = await runCli(['click_at', '100', '100'], sessionId); - assert.strictEqual(result.status, 0); assert( - result.stdout.includes( - 'Tool click_at requires experimental feature --experimentalVision and is currently disabled', - ), - 'error message is unexpected: ' + result.stdout, + result.stdout.includes('The performance trace has been stopped.'), + 'performance_start_trace output is unexpected: ' + result.stdout, ); assert( - result.stdout.includes('chrome-devtools start --experimentalVision=true'), - 'restart command suggestion is miss: ' + result.stdout, + result.stdout.includes('CPU throttling: none'), + 'performance_start_trace output is unexpected: ' + result.stdout, ); }); }); diff --git a/tests/tools/performance.test.ts b/tests/tools/performance.test.ts index 229f1da23..eeeb2f2df 100644 --- a/tests/tools/performance.test.ts +++ b/tests/tools/performance.test.ts @@ -48,6 +48,7 @@ describe('performance', () => { context.setIsRunningPerformanceTrace(false); const selectedPage = context.getSelectedPptrPage(); const startTracingStub = sinon.stub(selectedPage.tracing, 'start'); + const restoreEmulationSpy = sinon.spy(context, 'restoreEmulation'); await startTrace.handler( { params: {reload: true, autoStop: false}, @@ -57,6 +58,7 @@ describe('performance', () => { context, ); sinon.assert.calledOnce(startTracingStub); + sinon.assert.calledOnce(restoreEmulationSpy); assert.ok(context.isRunningPerformanceTrace()); assert.ok( response.responseLines @@ -109,6 +111,7 @@ describe('performance', () => { .callsFake(() => { return Promise.resolve(rawData); }); + sinon.stub(context, 'restoreEmulation').resolves(); const clock = sinon.useFakeTimers(); const handlerPromise = startTrace.handler( @@ -179,6 +182,7 @@ describe('performance', () => { sinon.stub(selectedPage, 'goto').callsFake(() => Promise.resolve(null)); sinon.stub(selectedPage.tracing, 'start'); sinon.stub(selectedPage.tracing, 'stop').resolves(rawData); + sinon.stub(context, 'restoreEmulation').resolves(); const saveFileStub = sinon .stub(context, 'saveFile') .resolves({filename: filePath}); From 4266f99ada7944916398e0f4023568b9a27f383e Mon Sep 17 00:00:00 2001 From: Wolfgang Beyer Date: Wed, 13 May 2026 15:55:59 +0000 Subject: [PATCH 2/3] output now works, but actual time is still too fast --- src/tools/ToolDefinition.ts | 2 + src/tools/performance.ts | 26 +++++---- src/trace-processing/parse.ts | 6 ++- src/trace.js | 61 ++++++++++++++++++++++ tests/e2e/chrome-devtools-commands.test.ts | 2 +- 5 files changed, 85 insertions(+), 12 deletions(-) create mode 100644 src/trace.js diff --git a/src/tools/ToolDefinition.ts b/src/tools/ToolDefinition.ts index 34cdd435e..9737f5eff 100644 --- a/src/tools/ToolDefinition.ts +++ b/src/tools/ToolDefinition.ts @@ -257,6 +257,8 @@ export type Context = Readonly<{ */ export type ContextPage = Readonly<{ readonly pptrPage: Page; + readonly cpuThrottlingRate: number; + readonly networkConditions: string | null; getAXNodeByUid(uid: string): TextSnapshotNode | undefined; getElementByUid(uid: string): Promise>; diff --git a/src/tools/performance.ts b/src/tools/performance.ts index 05fc7b44e..ef0b08bba 100644 --- a/src/tools/performance.ts +++ b/src/tools/performance.ts @@ -8,7 +8,6 @@ import zlib from 'node:zlib'; import {logger} from '../logger.js'; import {zod, DevTools} from '../third_party/index.js'; -import type {Page} from '../third_party/index.js'; import type {InsightName, TraceResult} from '../trace-processing/parse.js'; import { parseRawTraceBuffer, @@ -16,7 +15,7 @@ import { } from '../trace-processing/parse.js'; import {ToolCategory} from './categories.js'; -import type {Context, Response} from './ToolDefinition.js'; +import type {Context, Response, ContextPage} from './ToolDefinition.js'; import {definePageTool} from './ToolDefinition.js'; const filePathSchema = zod @@ -94,18 +93,22 @@ export const startTrace = definePageTool({ await page.pptrPage.tracing.start({ categories, }); - // await context.restoreEmulation(page); + await context.restoreEmulation(page); if (request.params.reload) { + // await page.pptrPage.goto(pageUrlForTracing, { + // waitUntil: ['load'], + // }); await page.pptrPage.goto(pageUrlForTracing, { - waitUntil: ['load'], - }); + waitUntil: 'networkidle0', + timeout: 60000 + }); } if (request.params.autoStop) { await new Promise(resolve => setTimeout(resolve, 5_000)); await stopTracingAndAppendOutput( - page.pptrPage, + page, response, context, request.params.filePath, @@ -137,7 +140,7 @@ export const stopTrace = definePageTool({ } const page = request.page; await stopTracingAndAppendOutput( - page.pptrPage, + page, response, context, request.params.filePath, @@ -184,13 +187,13 @@ export const analyzeInsight = definePageTool({ }); async function stopTracingAndAppendOutput( - page: Page, + page: ContextPage, response: Response, context: Context, filePath?: string, ): Promise { try { - const traceEventsBuffer = await page.tracing.stop(); + const traceEventsBuffer = await page.pptrPage.tracing.stop(); if (filePath && traceEventsBuffer) { let dataToWrite: Uint8Array = traceEventsBuffer; if (filePath.endsWith('.gz')) { @@ -213,7 +216,10 @@ async function stopTracingAndAppendOutput( `The raw trace data was saved to ${file.filename}.`, ); } - const result = await parseRawTraceBuffer(traceEventsBuffer); + const result = await parseRawTraceBuffer(traceEventsBuffer, { + cpuThrottling: page.cpuThrottlingRate > 1 ? page.cpuThrottlingRate : 20, + networkThrottling: page.networkConditions ?? undefined, + }); response.appendResponseLine('The performance trace has been stopped.'); if (traceResultIsSuccess(result)) { if (context.isCruxEnabled()) { diff --git a/src/trace-processing/parse.ts b/src/trace-processing/parse.ts index d1da581f2..1f0a99847 100644 --- a/src/trace-processing/parse.ts +++ b/src/trace-processing/parse.ts @@ -26,6 +26,10 @@ export interface TraceParseError { export async function parseRawTraceBuffer( buffer: Uint8Array | undefined, + metadata?: { + cpuThrottling?: number; + networkThrottling?: string; + }, ): Promise { engine.resetProcessor(); if (!buffer) { @@ -47,7 +51,7 @@ export async function parseRawTraceBuffer( | DevTools.TraceEngine.Types.Events.Event[]; const events = Array.isArray(data) ? data : data.traceEvents; - await engine.parse(events); + await engine.parse(events, {metadata}); const parsedTrace = engine.parsedTrace(); if (!parsedTrace) { return { diff --git a/src/trace.js b/src/trace.js new file mode 100644 index 000000000..16ec67b2d --- /dev/null +++ b/src/trace.js @@ -0,0 +1,61 @@ +import puppeteer from 'puppeteer'; + +(async () => { + console.log('Launching browser...'); + const browser = await puppeteer.launch({ + headless: "new", + args: ['--no-sandbox', '--disable-setuid-sandbox'] + }); + const page = await browser.newPage(); + + // Create a Chrome DevTools Protocol session to enable CPU throttling + // const client = await page.target().createCDPSession(); + // console.log('Enabling 20x CPU throttling...'); + // await client.send('Emulation.setCPUThrottlingRate', { rate: 20 }); + + await page.emulateCPUThrottling(20); + + const url = 'https://heise.de'; + const tracePath = 'trace.json'; + + console.log(`Starting performance trace for ${url}...`); + await page.tracing.start({ + path: tracePath, + categories: [ + '-*', + 'blink.console', + 'blink.user_timing', + 'devtools.timeline', + 'disabled-by-default-devtools.screenshot', + 'disabled-by-default-devtools.timeline', + 'disabled-by-default-devtools.timeline.invalidationTracking', + 'disabled-by-default-devtools.timeline.frame', + 'disabled-by-default-devtools.timeline.stack', + 'disabled-by-default-v8.cpu_profiler', + 'disabled-by-default-v8.cpu_profiler.hires', + 'latencyInfo', + 'loading', + 'disabled-by-default-lighthouse', + 'v8.execute', + 'v8', + ] + }); + + console.log(`Navigating to ${url}...`); + try { + await page.goto(url, { + waitUntil: 'networkidle0', + timeout: 60000 + }); + } catch (error) { + console.error(`Error navigating to ${url}: ${error.message}`); + } + + console.log('Stopping trace...'); + await page.tracing.stop(); + + console.log(`Trace saved to ${tracePath}`); + + await browser.close(); + console.log('Browser closed.'); +})(); diff --git a/tests/e2e/chrome-devtools-commands.test.ts b/tests/e2e/chrome-devtools-commands.test.ts index 30b8e65ab..0961839a1 100644 --- a/tests/e2e/chrome-devtools-commands.test.ts +++ b/tests/e2e/chrome-devtools-commands.test.ts @@ -125,7 +125,7 @@ describe('chrome-devtools', () => { 'performance_start_trace output is unexpected: ' + result.stdout, ); assert( - result.stdout.includes('CPU throttling: none'), + result.stdout.includes('CPU throttling: 20x'), 'performance_start_trace output is unexpected: ' + result.stdout, ); }); From 19451ed328b414f4e673b8ea5db7e4f723389537 Mon Sep 17 00:00:00 2001 From: Wolfgang Beyer Date: Thu, 21 May 2026 19:08:23 +0000 Subject: [PATCH 3/3] polishing --- src/McpContext.ts | 2 +- src/tools/performance.ts | 12 +- src/trace-processing/parse.ts | 6 - src/trace.js | 61 -------- tests/e2e/chrome-devtools-commands.test.ts | 174 +++++++++++---------- tests/tools/performance.test.ts | 4 - 6 files changed, 98 insertions(+), 161 deletions(-) delete mode 100644 src/trace.js diff --git a/src/McpContext.ts b/src/McpContext.ts index a77bc06bc..2916163cd 100644 --- a/src/McpContext.ts +++ b/src/McpContext.ts @@ -481,7 +481,7 @@ export class McpContext implements Context { page.networkConditions, ); page.pptrPage.setDefaultNavigationTimeout( - NAVIGATION_TIMEOUT * networkMultiplier, + NAVIGATION_TIMEOUT * networkMultiplier * cpuMultiplier, ); } diff --git a/src/tools/performance.ts b/src/tools/performance.ts index ef0b08bba..edd1bdf83 100644 --- a/src/tools/performance.ts +++ b/src/tools/performance.ts @@ -89,20 +89,14 @@ export const startTrace = definePageTool({ 'v8.execute', 'v8', ]; - await page.pptrPage.emulateCPUThrottling(20); await page.pptrPage.tracing.start({ categories, }); - await context.restoreEmulation(page); if (request.params.reload) { - // await page.pptrPage.goto(pageUrlForTracing, { - // waitUntil: ['load'], - // }); await page.pptrPage.goto(pageUrlForTracing, { - waitUntil: 'networkidle0', - timeout: 60000 - }); + waitUntil: ['load'], + }); } if (request.params.autoStop) { @@ -217,7 +211,7 @@ async function stopTracingAndAppendOutput( ); } const result = await parseRawTraceBuffer(traceEventsBuffer, { - cpuThrottling: page.cpuThrottlingRate > 1 ? page.cpuThrottlingRate : 20, + cpuThrottling: page.cpuThrottlingRate, networkThrottling: page.networkConditions ?? undefined, }); response.appendResponseLine('The performance trace has been stopped.'); diff --git a/src/trace-processing/parse.ts b/src/trace-processing/parse.ts index 1f0a99847..f0ede38db 100644 --- a/src/trace-processing/parse.ts +++ b/src/trace-processing/parse.ts @@ -80,15 +80,9 @@ ${DevTools.PerformanceTraceFormatter.callFrameDataFormatDescription} ${DevTools.PerformanceTraceFormatter.networkDataFormatDescription}`; -// here export function getTraceSummary(result: TraceResult): string { const focus = DevTools.AgentFocus.fromParsedTrace(result.parsedTrace); const formatter = new DevTools.PerformanceTraceFormatter(focus); - logger( - 'METADATA', - focus.parsedTrace.metadata, - JSON.stringify(focus.parsedTrace.metadata), - ); const summaryText = formatter.formatTraceSummary(); return `## Summary of Performance trace findings: ${summaryText} diff --git a/src/trace.js b/src/trace.js deleted file mode 100644 index 16ec67b2d..000000000 --- a/src/trace.js +++ /dev/null @@ -1,61 +0,0 @@ -import puppeteer from 'puppeteer'; - -(async () => { - console.log('Launching browser...'); - const browser = await puppeteer.launch({ - headless: "new", - args: ['--no-sandbox', '--disable-setuid-sandbox'] - }); - const page = await browser.newPage(); - - // Create a Chrome DevTools Protocol session to enable CPU throttling - // const client = await page.target().createCDPSession(); - // console.log('Enabling 20x CPU throttling...'); - // await client.send('Emulation.setCPUThrottlingRate', { rate: 20 }); - - await page.emulateCPUThrottling(20); - - const url = 'https://heise.de'; - const tracePath = 'trace.json'; - - console.log(`Starting performance trace for ${url}...`); - await page.tracing.start({ - path: tracePath, - categories: [ - '-*', - 'blink.console', - 'blink.user_timing', - 'devtools.timeline', - 'disabled-by-default-devtools.screenshot', - 'disabled-by-default-devtools.timeline', - 'disabled-by-default-devtools.timeline.invalidationTracking', - 'disabled-by-default-devtools.timeline.frame', - 'disabled-by-default-devtools.timeline.stack', - 'disabled-by-default-v8.cpu_profiler', - 'disabled-by-default-v8.cpu_profiler.hires', - 'latencyInfo', - 'loading', - 'disabled-by-default-lighthouse', - 'v8.execute', - 'v8', - ] - }); - - console.log(`Navigating to ${url}...`); - try { - await page.goto(url, { - waitUntil: 'networkidle0', - timeout: 60000 - }); - } catch (error) { - console.error(`Error navigating to ${url}: ${error.message}`); - } - - console.log('Stopping trace...'); - await page.tracing.stop(); - - console.log(`Trace saved to ${tracePath}`); - - await browser.close(); - console.log('Browser closed.'); -})(); diff --git a/tests/e2e/chrome-devtools-commands.test.ts b/tests/e2e/chrome-devtools-commands.test.ts index 0961839a1..97d23fb7d 100644 --- a/tests/e2e/chrome-devtools-commands.test.ts +++ b/tests/e2e/chrome-devtools-commands.test.ts @@ -8,7 +8,11 @@ import assert from 'node:assert'; import crypto from 'node:crypto'; import {describe, it, afterEach, beforeEach} from 'node:test'; -import {assertDaemonIsNotRunning, runCli} from '../utils.js'; +import { + assertDaemonIsNotRunning, + assertDaemonIsRunning, + runCli, +} from '../utils.js'; describe('chrome-devtools', () => { let sessionId: string; @@ -24,84 +28,84 @@ describe('chrome-devtools', () => { await assertDaemonIsNotRunning(sessionId); }); - // it('can invoke list_pages', async () => { - // await assertDaemonIsNotRunning(sessionId); - - // const startResult = await runCli(['start'], sessionId); - // assert.strictEqual( - // startResult.status, - // 0, - // `start command failed: ${startResult.stderr}`, - // ); - - // const listPagesResult = await runCli(['list_pages'], sessionId); - // assert.strictEqual( - // listPagesResult.status, - // 0, - // `list_pages command failed: ${listPagesResult.stderr}`, - // ); - // assert( - // listPagesResult.stdout.includes('about:blank'), - // 'list_pages output is unexpected', - // ); - - // await assertDaemonIsRunning(sessionId); - // }); - - // it('can take screenshot', async () => { - // const startResult = await runCli(['start'], sessionId); - // assert.strictEqual( - // startResult.status, - // 0, - // `start command failed: ${startResult.stderr}`, - // ); - - // const result = await runCli(['take_screenshot'], sessionId); - // assert.strictEqual( - // result.status, - // 0, - // `take_screenshot command failed: ${result.stderr}`, - // ); - // assert( - // result.stdout.includes('.png'), - // 'take_screenshot output is unexpected', - // ); - // }); - - // it('fails to invoke list_network_requests when categoryNetwork is disabled', async () => { - // await runCli(['start', '--categoryNetwork=false'], sessionId); - - // const result = await runCli(['list_network_requests'], sessionId); - // assert.strictEqual(result.status, 0); - - // assert( - // result.stdout.includes( - // 'Tool list_network_requests is in category Network which is currently disabled', - // ), - // 'error message is unexpected: ' + result.stdout, - // ); - // assert( - // result.stdout.includes('chrome-devtools start --categoryNetwork=true'), - // 'restart command suggestion is missing: ' + result.stdout, - // ); - // }); - - // it('fails to invoke click_at when experimentalVision is disabled (default)', async () => { - // await runCli(['start'], sessionId); - - // const result = await runCli(['click_at', '100', '100'], sessionId); - // assert.strictEqual(result.status, 0); - // assert( - // result.stdout.includes( - // 'Tool click_at requires experimental feature --experimentalVision and is currently disabled', - // ), - // 'error message is unexpected: ' + result.stdout, - // ); - // assert( - // result.stdout.includes('chrome-devtools start --experimentalVision=true'), - // 'restart command suggestion is miss: ' + result.stdout, - // ); - // }); + it('can invoke list_pages', async () => { + await assertDaemonIsNotRunning(sessionId); + + const startResult = await runCli(['start'], sessionId); + assert.strictEqual( + startResult.status, + 0, + `start command failed: ${startResult.stderr}`, + ); + + const listPagesResult = await runCli(['list_pages'], sessionId); + assert.strictEqual( + listPagesResult.status, + 0, + `list_pages command failed: ${listPagesResult.stderr}`, + ); + assert( + listPagesResult.stdout.includes('about:blank'), + 'list_pages output is unexpected', + ); + + await assertDaemonIsRunning(sessionId); + }); + + it('can take screenshot', async () => { + const startResult = await runCli(['start'], sessionId); + assert.strictEqual( + startResult.status, + 0, + `start command failed: ${startResult.stderr}`, + ); + + const result = await runCli(['take_screenshot'], sessionId); + assert.strictEqual( + result.status, + 0, + `take_screenshot command failed: ${result.stderr}`, + ); + assert( + result.stdout.includes('.png'), + 'take_screenshot output is unexpected', + ); + }); + + it('fails to invoke list_network_requests when categoryNetwork is disabled', async () => { + await runCli(['start', '--categoryNetwork=false'], sessionId); + + const result = await runCli(['list_network_requests'], sessionId); + assert.strictEqual(result.status, 0); + + assert( + result.stdout.includes( + 'Tool list_network_requests is in category Network which is currently disabled', + ), + 'error message is unexpected: ' + result.stdout, + ); + assert( + result.stdout.includes('chrome-devtools start --categoryNetwork=true'), + 'restart command suggestion is missing: ' + result.stdout, + ); + }); + + it('fails to invoke click_at when experimentalVision is disabled (default)', async () => { + await runCli(['start'], sessionId); + + const result = await runCli(['click_at', '100', '100'], sessionId); + assert.strictEqual(result.status, 0); + assert( + result.stdout.includes( + 'Tool click_at requires experimental feature --experimentalVision and is currently disabled', + ), + 'error message is unexpected: ' + result.stdout, + ); + assert( + result.stdout.includes('chrome-devtools start --experimentalVision=true'), + 'restart command suggestion is miss: ' + result.stdout, + ); + }); it('can record a performance trace', async () => { const startResult = await runCli( @@ -114,6 +118,16 @@ describe('chrome-devtools', () => { `start command failed: ${startResult.stderr}`, ); + const emulateResult = await runCli( + ['emulate', '--cpuThrottlingRate', '2'], + sessionId, + ); + assert.strictEqual( + emulateResult.status, + 0, + `emulate command failed: ${emulateResult.stderr}`, + ); + const result = await runCli(['performance_start_trace'], sessionId); assert.strictEqual( result.status, @@ -125,7 +139,7 @@ describe('chrome-devtools', () => { 'performance_start_trace output is unexpected: ' + result.stdout, ); assert( - result.stdout.includes('CPU throttling: 20x'), + result.stdout.includes('CPU throttling: 2x'), 'performance_start_trace output is unexpected: ' + result.stdout, ); }); diff --git a/tests/tools/performance.test.ts b/tests/tools/performance.test.ts index eeeb2f2df..229f1da23 100644 --- a/tests/tools/performance.test.ts +++ b/tests/tools/performance.test.ts @@ -48,7 +48,6 @@ describe('performance', () => { context.setIsRunningPerformanceTrace(false); const selectedPage = context.getSelectedPptrPage(); const startTracingStub = sinon.stub(selectedPage.tracing, 'start'); - const restoreEmulationSpy = sinon.spy(context, 'restoreEmulation'); await startTrace.handler( { params: {reload: true, autoStop: false}, @@ -58,7 +57,6 @@ describe('performance', () => { context, ); sinon.assert.calledOnce(startTracingStub); - sinon.assert.calledOnce(restoreEmulationSpy); assert.ok(context.isRunningPerformanceTrace()); assert.ok( response.responseLines @@ -111,7 +109,6 @@ describe('performance', () => { .callsFake(() => { return Promise.resolve(rawData); }); - sinon.stub(context, 'restoreEmulation').resolves(); const clock = sinon.useFakeTimers(); const handlerPromise = startTrace.handler( @@ -182,7 +179,6 @@ describe('performance', () => { sinon.stub(selectedPage, 'goto').callsFake(() => Promise.resolve(null)); sinon.stub(selectedPage.tracing, 'start'); sinon.stub(selectedPage.tracing, 'stop').resolves(rawData); - sinon.stub(context, 'restoreEmulation').resolves(); const saveFileStub = sinon .stub(context, 'saveFile') .resolves({filename: filePath});