mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
feat(trace viewer): Adds _debugName BrowserContextOption to let users define a name for their contexts (#5205)
This change is adding a new property on the BrowserContextOptions class called `_debugName`. This property allows defining a user-friendly name for the browser context, and currently it is being used in one place, the Trace Viewer. When user provides the new value in the following way:
```typescript
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
const context = await browser.newContext({ _traceDir: __dirname, _debugName: 'My custom testcase name' });
await context.close();
await browser.close();
})();
```
The `_debugName` will be saved in the `*.trace` file for this browser context, on the `context-created` event, under the key `debugName`.
Later, when such a trace is displayed using Trace Viewer, the `debugName` will be displayed in the dropdown in the top right part of the app instead of the actual trace filename.
Fixes #5157.
This commit is contained in:
parent
8d8fa4c322
commit
f8fbfe28fa
@ -73,7 +73,7 @@ export function readTraceFile(events: trace.TraceEvent[], traceModel: TraceModel
|
|||||||
case 'context-created': {
|
case 'context-created': {
|
||||||
contextEntries.set(event.contextId, {
|
contextEntries.set(event.contextId, {
|
||||||
filePath,
|
filePath,
|
||||||
name: filePath.substring(filePath.lastIndexOf('/') + 1),
|
name: event.debugName || filePath.substring(filePath.lastIndexOf('/') + 1),
|
||||||
startTime: Number.MAX_VALUE,
|
startTime: Number.MAX_VALUE,
|
||||||
endTime: Number.MIN_VALUE,
|
endTime: Number.MIN_VALUE,
|
||||||
created: event,
|
created: event,
|
||||||
|
|||||||
@ -298,6 +298,7 @@ export type BrowserTypeLaunchPersistentContextParams = {
|
|||||||
colorScheme?: 'light' | 'dark' | 'no-preference',
|
colorScheme?: 'light' | 'dark' | 'no-preference',
|
||||||
acceptDownloads?: boolean,
|
acceptDownloads?: boolean,
|
||||||
_traceDir?: string,
|
_traceDir?: string,
|
||||||
|
_debugName?: string,
|
||||||
recordVideo?: {
|
recordVideo?: {
|
||||||
dir: string,
|
dir: string,
|
||||||
size?: {
|
size?: {
|
||||||
@ -360,6 +361,7 @@ export type BrowserTypeLaunchPersistentContextOptions = {
|
|||||||
colorScheme?: 'light' | 'dark' | 'no-preference',
|
colorScheme?: 'light' | 'dark' | 'no-preference',
|
||||||
acceptDownloads?: boolean,
|
acceptDownloads?: boolean,
|
||||||
_traceDir?: string,
|
_traceDir?: string,
|
||||||
|
_debugName?: string,
|
||||||
recordVideo?: {
|
recordVideo?: {
|
||||||
dir: string,
|
dir: string,
|
||||||
size?: {
|
size?: {
|
||||||
@ -423,6 +425,7 @@ export type BrowserNewContextParams = {
|
|||||||
colorScheme?: 'dark' | 'light' | 'no-preference',
|
colorScheme?: 'dark' | 'light' | 'no-preference',
|
||||||
acceptDownloads?: boolean,
|
acceptDownloads?: boolean,
|
||||||
_traceDir?: string,
|
_traceDir?: string,
|
||||||
|
_debugName?: string,
|
||||||
recordVideo?: {
|
recordVideo?: {
|
||||||
dir: string,
|
dir: string,
|
||||||
size?: {
|
size?: {
|
||||||
@ -475,6 +478,7 @@ export type BrowserNewContextOptions = {
|
|||||||
colorScheme?: 'dark' | 'light' | 'no-preference',
|
colorScheme?: 'dark' | 'light' | 'no-preference',
|
||||||
acceptDownloads?: boolean,
|
acceptDownloads?: boolean,
|
||||||
_traceDir?: string,
|
_traceDir?: string,
|
||||||
|
_debugName?: string,
|
||||||
recordVideo?: {
|
recordVideo?: {
|
||||||
dir: string,
|
dir: string,
|
||||||
size?: {
|
size?: {
|
||||||
@ -2795,6 +2799,7 @@ export type AndroidDeviceLaunchBrowserParams = {
|
|||||||
colorScheme?: 'dark' | 'light' | 'no-preference',
|
colorScheme?: 'dark' | 'light' | 'no-preference',
|
||||||
acceptDownloads?: boolean,
|
acceptDownloads?: boolean,
|
||||||
_traceDir?: string,
|
_traceDir?: string,
|
||||||
|
_debugName?: string,
|
||||||
recordVideo?: {
|
recordVideo?: {
|
||||||
dir: string,
|
dir: string,
|
||||||
size?: {
|
size?: {
|
||||||
@ -2839,6 +2844,7 @@ export type AndroidDeviceLaunchBrowserOptions = {
|
|||||||
colorScheme?: 'dark' | 'light' | 'no-preference',
|
colorScheme?: 'dark' | 'light' | 'no-preference',
|
||||||
acceptDownloads?: boolean,
|
acceptDownloads?: boolean,
|
||||||
_traceDir?: string,
|
_traceDir?: string,
|
||||||
|
_debugName?: string,
|
||||||
recordVideo?: {
|
recordVideo?: {
|
||||||
dir: string,
|
dir: string,
|
||||||
size?: {
|
size?: {
|
||||||
|
|||||||
@ -373,6 +373,7 @@ BrowserType:
|
|||||||
- no-preference
|
- no-preference
|
||||||
acceptDownloads: boolean?
|
acceptDownloads: boolean?
|
||||||
_traceDir: string?
|
_traceDir: string?
|
||||||
|
_debugName: string?
|
||||||
recordVideo:
|
recordVideo:
|
||||||
type: object?
|
type: object?
|
||||||
properties:
|
properties:
|
||||||
@ -445,6 +446,7 @@ Browser:
|
|||||||
- no-preference
|
- no-preference
|
||||||
acceptDownloads: boolean?
|
acceptDownloads: boolean?
|
||||||
_traceDir: string?
|
_traceDir: string?
|
||||||
|
_debugName: string?
|
||||||
recordVideo:
|
recordVideo:
|
||||||
type: object?
|
type: object?
|
||||||
properties:
|
properties:
|
||||||
@ -2352,6 +2354,7 @@ AndroidDevice:
|
|||||||
- no-preference
|
- no-preference
|
||||||
acceptDownloads: boolean?
|
acceptDownloads: boolean?
|
||||||
_traceDir: string?
|
_traceDir: string?
|
||||||
|
_debugName: string?
|
||||||
recordVideo:
|
recordVideo:
|
||||||
type: object?
|
type: object?
|
||||||
properties:
|
properties:
|
||||||
|
|||||||
@ -212,6 +212,7 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme {
|
|||||||
colorScheme: tOptional(tEnum(['light', 'dark', 'no-preference'])),
|
colorScheme: tOptional(tEnum(['light', 'dark', 'no-preference'])),
|
||||||
acceptDownloads: tOptional(tBoolean),
|
acceptDownloads: tOptional(tBoolean),
|
||||||
_traceDir: tOptional(tString),
|
_traceDir: tOptional(tString),
|
||||||
|
_debugName: tOptional(tString),
|
||||||
recordVideo: tOptional(tObject({
|
recordVideo: tOptional(tObject({
|
||||||
dir: tString,
|
dir: tString,
|
||||||
size: tOptional(tObject({
|
size: tOptional(tObject({
|
||||||
@ -255,6 +256,7 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme {
|
|||||||
colorScheme: tOptional(tEnum(['dark', 'light', 'no-preference'])),
|
colorScheme: tOptional(tEnum(['dark', 'light', 'no-preference'])),
|
||||||
acceptDownloads: tOptional(tBoolean),
|
acceptDownloads: tOptional(tBoolean),
|
||||||
_traceDir: tOptional(tString),
|
_traceDir: tOptional(tString),
|
||||||
|
_debugName: tOptional(tString),
|
||||||
recordVideo: tOptional(tObject({
|
recordVideo: tOptional(tObject({
|
||||||
dir: tString,
|
dir: tString,
|
||||||
size: tOptional(tObject({
|
size: tOptional(tObject({
|
||||||
@ -1046,6 +1048,7 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme {
|
|||||||
colorScheme: tOptional(tEnum(['dark', 'light', 'no-preference'])),
|
colorScheme: tOptional(tEnum(['dark', 'light', 'no-preference'])),
|
||||||
acceptDownloads: tOptional(tBoolean),
|
acceptDownloads: tOptional(tBoolean),
|
||||||
_traceDir: tOptional(tString),
|
_traceDir: tOptional(tString),
|
||||||
|
_debugName: tOptional(tString),
|
||||||
recordVideo: tOptional(tObject({
|
recordVideo: tOptional(tObject({
|
||||||
dir: tString,
|
dir: tString,
|
||||||
size: tOptional(tObject({
|
size: tOptional(tObject({
|
||||||
|
|||||||
@ -249,6 +249,7 @@ export type BrowserContextOptions = {
|
|||||||
},
|
},
|
||||||
proxy?: ProxySettings,
|
proxy?: ProxySettings,
|
||||||
_traceDir?: string,
|
_traceDir?: string,
|
||||||
|
_debugName?: string,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type EnvArray = { name: string, value: string }[];
|
export type EnvArray = { name: string, value: string }[];
|
||||||
|
|||||||
@ -22,6 +22,7 @@ export type ContextCreatedTraceEvent = {
|
|||||||
deviceScaleFactor: number,
|
deviceScaleFactor: number,
|
||||||
isMobile: boolean,
|
isMobile: boolean,
|
||||||
viewportSize?: { width: number, height: number },
|
viewportSize?: { width: number, height: number },
|
||||||
|
debugName?: string,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ContextDestroyedTraceEvent = {
|
export type ContextDestroyedTraceEvent = {
|
||||||
|
|||||||
@ -97,6 +97,7 @@ class ContextTracer implements SnapshotterDelegate, ActionListener {
|
|||||||
isMobile: !!context._options.isMobile,
|
isMobile: !!context._options.isMobile,
|
||||||
deviceScaleFactor: context._options.deviceScaleFactor || 1,
|
deviceScaleFactor: context._options.deviceScaleFactor || 1,
|
||||||
viewportSize: context._options.viewport || undefined,
|
viewportSize: context._options.viewport || undefined,
|
||||||
|
debugName: context._options._debugName,
|
||||||
};
|
};
|
||||||
this._appendTraceEvent(event);
|
this._appendTraceEvent(event);
|
||||||
this._snapshotter = new Snapshotter(context, this);
|
this._snapshotter = new Snapshotter(context, this);
|
||||||
|
|||||||
@ -35,6 +35,7 @@ it('should record trace', (test, { browserName, platform }) => {
|
|||||||
|
|
||||||
const contextEvent = traceEvents.find(event => event.type === 'context-created') as trace.ContextCreatedTraceEvent;
|
const contextEvent = traceEvents.find(event => event.type === 'context-created') as trace.ContextCreatedTraceEvent;
|
||||||
expect(contextEvent).toBeTruthy();
|
expect(contextEvent).toBeTruthy();
|
||||||
|
expect(contextEvent.debugName).toBeUndefined();
|
||||||
const contextId = contextEvent.contextId;
|
const contextId = contextEvent.contextId;
|
||||||
|
|
||||||
const pageEvent = traceEvents.find(event => event.type === 'page-created') as trace.PageCreatedTraceEvent;
|
const pageEvent = traceEvents.find(event => event.type === 'page-created') as trace.PageCreatedTraceEvent;
|
||||||
@ -84,6 +85,7 @@ it('should record trace with POST', (test, { browserName, platform }) => {
|
|||||||
|
|
||||||
const contextEvent = traceEvents.find(event => event.type === 'context-created') as trace.ContextCreatedTraceEvent;
|
const contextEvent = traceEvents.find(event => event.type === 'context-created') as trace.ContextCreatedTraceEvent;
|
||||||
expect(contextEvent).toBeTruthy();
|
expect(contextEvent).toBeTruthy();
|
||||||
|
expect(contextEvent.debugName).toBeUndefined();
|
||||||
const contextId = contextEvent.contextId;
|
const contextId = contextEvent.contextId;
|
||||||
|
|
||||||
const pageEvent = traceEvents.find(event => event.type === 'page-created') as trace.PageCreatedTraceEvent;
|
const pageEvent = traceEvents.find(event => event.type === 'page-created') as trace.PageCreatedTraceEvent;
|
||||||
@ -111,3 +113,19 @@ it('should record trace with POST', (test, { browserName, platform }) => {
|
|||||||
expect(fs.existsSync(path.join(traceDir, 'resources', resourceEvent.requestSha1))).toBe(true);
|
expect(fs.existsSync(path.join(traceDir, 'resources', resourceEvent.requestSha1))).toBe(true);
|
||||||
expect(fs.existsSync(path.join(traceDir, 'resources', resourceEvent.responseSha1))).toBe(true);
|
expect(fs.existsSync(path.join(traceDir, 'resources', resourceEvent.responseSha1))).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should record trace with a debugName', (test, { browserName, platform }) => {
|
||||||
|
test.fixme();
|
||||||
|
}, async ({browser, testInfo, server}) => {
|
||||||
|
const traceDir = testInfo.outputPath('trace');
|
||||||
|
const debugName = 'Custom testcase name';
|
||||||
|
const context = await browser.newContext({ _traceDir: traceDir, _debugName: debugName } as any);
|
||||||
|
await context.close();
|
||||||
|
const tracePath = path.join(traceDir, fs.readdirSync(traceDir).find(n => n.endsWith('.trace')));
|
||||||
|
const traceFileContent = await fs.promises.readFile(tracePath, 'utf8');
|
||||||
|
const traceEvents = traceFileContent.split('\n').filter(line => !!line).map(line => JSON.parse(line)) as trace.TraceEvent[];
|
||||||
|
|
||||||
|
const contextEvent = traceEvents.find(event => event.type === 'context-created') as trace.ContextCreatedTraceEvent;
|
||||||
|
expect(contextEvent).toBeTruthy();
|
||||||
|
expect(contextEvent.debugName).toBe(debugName);
|
||||||
|
});
|
||||||
Loading…
x
Reference in New Issue
Block a user