This repository has been archived by the owner on Sep 6, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
74 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,40 +1,78 @@ | ||
import { promises as fs } from 'fs'; | ||
import { join } from 'path'; | ||
import { AfterAllHook, BeforeAllHook, RootCausePage } from '../interfaces'; | ||
import { getChromeCDPSession, sendCDPMessage } from '../utils'; | ||
import { NOOP_HOOK } from './hookUtils'; | ||
import { | ||
AfterAllHook, | ||
BeforeAllHook, | ||
IAutomationFrameworkInstrumentor, | ||
RootCausePage, | ||
} from '../interfaces'; | ||
import { getChromeCDPSession, isPlaywrightPage, sendCDPMessage } from '../utils'; | ||
|
||
export interface ProfilingHooks { | ||
startProfilingHook: BeforeAllHook; | ||
stopProfilingHook: AfterAllHook; | ||
export async function instrumentProfilingHooks( | ||
instrumentor: IAutomationFrameworkInstrumentor, | ||
page: RootCausePage | ||
) { | ||
await instrumentCDPBasedHooks(instrumentor, page); | ||
await instrumentPerformanceTrace(instrumentor, page); | ||
} | ||
|
||
export async function createProfilingHooks(page: RootCausePage): Promise<ProfilingHooks> { | ||
async function instrumentPerformanceTrace( | ||
instrumentor: IAutomationFrameworkInstrumentor, | ||
page: RootCausePage | ||
) { | ||
if (isPlaywrightPage(page)) { | ||
return; | ||
} | ||
|
||
const traceOutputFileName = 'performanceTrace.json'; | ||
|
||
const setup: BeforeAllHook = async function startPerformanceTraceHook({ testContext }) { | ||
const outputPath = join(testContext.testArtifactsFolder, traceOutputFileName); | ||
await page.tracing.start({ | ||
path: outputPath, | ||
}); | ||
|
||
// TODO: it's kinda annoying that you have to create a separate hook for teardown. | ||
// I'd expect to be able to do something like returning TeardownLogic like in RxJS. | ||
}; | ||
|
||
const teardown: AfterAllHook = async function stopPerformanceTraceHook({ testContext }) { | ||
await page.tracing.stop(); | ||
testContext.addTestMetadata({ traceOutputFileName }); | ||
}; | ||
|
||
instrumentor.registerBeforeAllHook(setup); | ||
instrumentor.registerAfterAllHook(teardown); | ||
} | ||
|
||
// example taken from https://github.com/paulirish/automated-chrome-profiling/blob/master/get-cpu-profile.js | ||
async function instrumentCDPBasedHooks( | ||
instrumentor: IAutomationFrameworkInstrumentor, | ||
page: RootCausePage | ||
) { | ||
const session = await getChromeCDPSession(page); | ||
|
||
if (!session) { | ||
return { | ||
startProfilingHook: NOOP_HOOK, | ||
stopProfilingHook: NOOP_HOOK, | ||
}; | ||
return; | ||
} | ||
|
||
// example taken from https://github.com/paulirish/automated-chrome-profiling/blob/master/get-cpu-profile.js | ||
return { | ||
async startProfilingHook() { | ||
await sendCDPMessage(session, 'Profiler.enable'); | ||
await sendCDPMessage(session, 'Profiler.setSamplingInterval', { | ||
interval: 100, | ||
}); | ||
await sendCDPMessage(session, 'Profiler.start'); | ||
}, | ||
async stopProfilingHook({ testContext }) { | ||
const { profile } = await sendCDPMessage(session, 'Profiler.stop'); | ||
|
||
const profilingFile = `profile.cpuprofile`; | ||
const outputFilePath = join(testContext.testArtifactsFolder, profilingFile); | ||
await fs.writeFile(outputFilePath, JSON.stringify(profile, null, 2)); | ||
testContext.addTestMetadata({ profilingFile }); | ||
}, | ||
const setup: BeforeAllHook = async function startCpuProfilingHook() { | ||
await sendCDPMessage(session, 'Profiler.enable'); | ||
await sendCDPMessage(session, 'Profiler.setSamplingInterval', { | ||
interval: 100, | ||
}); | ||
await sendCDPMessage(session, 'Profiler.start'); | ||
}; | ||
|
||
const teardown: AfterAllHook = async function stopCpuProfilingHook({ testContext }) { | ||
const { profile } = await sendCDPMessage(session, 'Profiler.stop'); | ||
|
||
const profilingFile = `profile.cpuprofile`; | ||
const outputFilePath = join(testContext.testArtifactsFolder, profilingFile); | ||
await fs.writeFile(outputFilePath, JSON.stringify(profile, null, 2)); | ||
testContext.addTestMetadata({ profilingFile }); | ||
}; | ||
|
||
instrumentor.registerBeforeAllHook(setup); | ||
instrumentor.registerAfterAllHook(teardown); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters