feat(recorder): display primary page URL in recorder title
This commit is contained in:
parent
25ef2f1344
commit
c6644f92bd
|
|
@ -32,6 +32,7 @@ import type * as actions from '@recorder/actions';
|
|||
import { stringifySelector } from '../utils/isomorphic/selectorParser';
|
||||
import type { Frame } from './frames';
|
||||
import type { AriaTemplateNode } from '@isomorphic/ariaSnapshot';
|
||||
import { Page } from './page';
|
||||
|
||||
const recorderSymbol = Symbol('recorderSymbol');
|
||||
|
||||
|
|
@ -148,6 +149,31 @@ export class Recorder implements InstrumentationListener, IRecorder {
|
|||
this._context.instrumentation.removeListener(this);
|
||||
this._recorderApp?.close().catch(() => {});
|
||||
});
|
||||
|
||||
// Report the URL of the first page in the context
|
||||
let primaryPage: Page | undefined;
|
||||
const registerNavigationListener = (page: Page) => {
|
||||
if (primaryPage === undefined) {
|
||||
primaryPage = page;
|
||||
recorderApp.setBasePageURL(page.mainFrame().url());
|
||||
}
|
||||
|
||||
page.on(Page.Events.InternalFrameNavigatedToNewDocument, (frame: Frame) => {
|
||||
if (page === primaryPage && page.mainFrame() === frame)
|
||||
recorderApp.setBasePageURL(frame.url());
|
||||
});
|
||||
page.on(Page.Events.Close, () => {
|
||||
if (page === primaryPage) {
|
||||
primaryPage = this._context.pages()[0];
|
||||
if (primaryPage)
|
||||
recorderApp.setBasePageURL(primaryPage.mainFrame().url());
|
||||
}
|
||||
});
|
||||
};
|
||||
for (const page of this._context.pages())
|
||||
registerNavigationListener(page);
|
||||
this._context.on(BrowserContext.Events.Page, registerNavigationListener);
|
||||
|
||||
this._contextRecorder.on(ContextRecorder.Events.Change, (data: { sources: Source[], actions: actions.ActionInContext[] }) => {
|
||||
this._recorderSources = data.sources;
|
||||
recorderApp.setActions(data.actions, data.sources);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ export class EmptyRecorderApp extends EventEmitter implements IRecorderApp {
|
|||
async updateCallLogs(callLogs: CallLog[]): Promise<void> {}
|
||||
async setSources(sources: Source[]): Promise<void> {}
|
||||
async setActions(actions: actions.ActionInContext[], sources: Source[]): Promise<void> {}
|
||||
async setBasePageURL(url: string): Promise<void> {}
|
||||
}
|
||||
|
||||
export class RecorderApp extends EventEmitter implements IRecorderApp {
|
||||
|
|
@ -158,6 +159,12 @@ export class RecorderApp extends EventEmitter implements IRecorderApp {
|
|||
async setActions(actions: actions.ActionInContext[], sources: Source[]): Promise<void> {
|
||||
}
|
||||
|
||||
async setBasePageURL(url: string): Promise<void> {
|
||||
await this._page.mainFrame().evaluateExpression(((url: string) => {
|
||||
window.playwrightSetBasePageURL(url);
|
||||
}).toString(), { isFunction: true }, url).catch(() => {});
|
||||
}
|
||||
|
||||
async elementPicked(elementInfo: ElementInfo, userGesture?: boolean): Promise<void> {
|
||||
if (userGesture)
|
||||
this._page.bringToFront();
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ export interface IRecorderApp extends EventEmitter {
|
|||
updateCallLogs(callLogs: CallLog[]): Promise<void>;
|
||||
setSources(sources: Source[]): Promise<void>;
|
||||
setActions(actions: actions.ActionInContext[], sources: Source[]): Promise<void>;
|
||||
setBasePageURL(url: string): Promise<void>;
|
||||
}
|
||||
|
||||
export type IRecorderAppFactory = (recorder: IRecorder) => Promise<IRecorderApp>;
|
||||
|
|
|
|||
|
|
@ -26,22 +26,31 @@ export const Main: React.FC = ({
|
|||
const [log, setLog] = React.useState(new Map<string, CallLog>());
|
||||
const [mode, setMode] = React.useState<Mode>('none');
|
||||
|
||||
window.playwrightSetMode = setMode;
|
||||
window.playwrightSetSources = React.useCallback((sources: Source[]) => {
|
||||
setSources(sources);
|
||||
window.playwrightSourcesEchoForTest = sources;
|
||||
React.useLayoutEffect(() => {
|
||||
window.playwrightSetMode = setMode;
|
||||
window.playwrightSetSources = (sources: Source[]) => {
|
||||
setSources(sources);
|
||||
window.playwrightSourcesEchoForTest = sources;
|
||||
};
|
||||
window.playwrightSetPaused = setPaused;
|
||||
window.playwrightUpdateLogs = callLogs => {
|
||||
setLog(log => {
|
||||
const newLog = new Map<string, CallLog>(log);
|
||||
for (const callLog of callLogs) {
|
||||
callLog.reveal = !log.has(callLog.id);
|
||||
newLog.set(callLog.id, callLog);
|
||||
}
|
||||
return newLog;
|
||||
});
|
||||
};
|
||||
window.playwrightSetBasePageURL = (url: string) => {
|
||||
if (url)
|
||||
document.title = `Playwright Inspector - ${url}`;
|
||||
else
|
||||
document.title = `Playwright Inspector`;
|
||||
};
|
||||
}, []);
|
||||
window.playwrightSetPaused = setPaused;
|
||||
window.playwrightUpdateLogs = callLogs => {
|
||||
setLog(log => {
|
||||
const newLog = new Map<string, CallLog>(log);
|
||||
for (const callLog of callLogs) {
|
||||
callLog.reveal = !log.has(callLog.id);
|
||||
newLog.set(callLog.id, callLog);
|
||||
}
|
||||
return newLog;
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
return <Recorder sources={sources} paused={paused} log={log} mode={mode} />;
|
||||
};
|
||||
|
|
|
|||
1
packages/recorder/src/recorderTypes.d.ts
vendored
1
packages/recorder/src/recorderTypes.d.ts
vendored
|
|
@ -103,6 +103,7 @@ declare global {
|
|||
playwrightSetPaused: (paused: boolean) => void;
|
||||
playwrightSetSources: (sources: Source[]) => void;
|
||||
playwrightSetOverlayVisible: (visible: boolean) => void;
|
||||
playwrightSetBasePageURL: (url: string) => void;
|
||||
playwrightUpdateLogs: (callLogs: CallLog[]) => void;
|
||||
playwrightSetRunningFile: (file: string | undefined) => void;
|
||||
playwrightElementPicked: (elementInfo: ElementInfo, userGesture?: boolean) => void;
|
||||
|
|
|
|||
53
tests/library/inspector/title.spec.ts
Normal file
53
tests/library/inspector/title.spec.ts
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { test, expect } from './inspectorTest';
|
||||
|
||||
test('should reflect formatted URL of the page', async ({ openRecorder, server }) => {
|
||||
const { recorder } = await openRecorder();
|
||||
await recorder.setContentAndWait('');
|
||||
await expect(await recorder.recorderPage.title()).toBe('Playwright Inspector - about:blank');
|
||||
|
||||
await recorder.setContentAndWait('', server.EMPTY_PAGE);
|
||||
await expect(await recorder.recorderPage.title()).toBe(`Playwright Inspector - ${server.EMPTY_PAGE}`);
|
||||
});
|
||||
|
||||
test('should update primary page URL when original primary closes', async ({ context, openRecorder, server }) => {
|
||||
const { recorder } = await openRecorder();
|
||||
await recorder.setContentAndWait('', `${server.PREFIX}/background-color.html`);
|
||||
await expect(await recorder.recorderPage.title()).toBe(`Playwright Inspector - ${server.PREFIX}/background-color.html`);
|
||||
|
||||
const page2 = await context.newPage();
|
||||
await page2.goto(`${server.PREFIX}/empty.html`);
|
||||
await expect(await recorder.recorderPage.title()).toBe(`Playwright Inspector - ${server.PREFIX}/background-color.html`);
|
||||
|
||||
const page3 = await context.newPage();
|
||||
await page3.goto(`${server.PREFIX}/dom.html`);
|
||||
await expect(await recorder.recorderPage.title()).toBe(`Playwright Inspector - ${server.PREFIX}/background-color.html`);
|
||||
|
||||
const page4 = await context.newPage();
|
||||
await page4.goto(`${server.PREFIX}/grid.html`);
|
||||
await expect(await recorder.recorderPage.title()).toBe(`Playwright Inspector - ${server.PREFIX}/background-color.html`);
|
||||
|
||||
await page2.close();
|
||||
await expect(await recorder.recorderPage.title()).toBe(`Playwright Inspector - ${server.PREFIX}/background-color.html`);
|
||||
|
||||
await recorder.page.close();
|
||||
await expect(await recorder.recorderPage.title()).toBe(`Playwright Inspector - ${server.PREFIX}/dom.html`);
|
||||
|
||||
await page3.close();
|
||||
await expect(await recorder.recorderPage.title()).toBe(`Playwright Inspector - ${server.PREFIX}/grid.html`);
|
||||
});
|
||||
Loading…
Reference in a new issue