fix(debug controller): highlight selectors in iframe (#33273)
This commit is contained in:
parent
96a29b69eb
commit
b148ce1ad1
|
@ -30,6 +30,8 @@ import type { IRecorderAppFactory, IRecorderApp, IRecorder } from './recorder/re
|
|||
import { metadataToCallLog } from './recorder/recorderUtils';
|
||||
import type * as actions from '@recorder/actions';
|
||||
import { buildFullSelector } from '../utils/isomorphic/recorderUtils';
|
||||
import { stringifySelector } from '../utils/isomorphic/selectorParser';
|
||||
import type { Frame } from './frames';
|
||||
|
||||
const recorderSymbol = Symbol('recorderSymbol');
|
||||
|
||||
|
@ -146,12 +148,12 @@ export class Recorder implements InstrumentationListener, IRecorder {
|
|||
this._pushAllSources();
|
||||
});
|
||||
|
||||
await this._context.exposeBinding('__pw_recorderState', false, source => {
|
||||
await this._context.exposeBinding('__pw_recorderState', false, async source => {
|
||||
let actionSelector = '';
|
||||
let actionPoint: Point | undefined;
|
||||
const hasActiveScreenshotCommand = [...this._currentCallsMetadata.keys()].some(isScreenshotCommand);
|
||||
if (!hasActiveScreenshotCommand) {
|
||||
actionSelector = this._highlightedSelector;
|
||||
actionSelector = await this._scopeHighlightedSelectorToFrame(source.frame);
|
||||
for (const [metadata, sdkObject] of this._currentCallsMetadata) {
|
||||
if (source.page === sdkObject.attribution.page) {
|
||||
actionPoint = metadata.point || actionPoint;
|
||||
|
@ -243,13 +245,38 @@ export class Recorder implements InstrumentationListener, IRecorder {
|
|||
this._refreshOverlay();
|
||||
}
|
||||
|
||||
private async _scopeHighlightedSelectorToFrame(frame: Frame): Promise<string> {
|
||||
try {
|
||||
const mainFrame = frame._page.mainFrame();
|
||||
const resolved = await mainFrame.selectors.resolveFrameForSelector(this._highlightedSelector);
|
||||
// selector couldn't be found, don't highlight anything
|
||||
if (!resolved)
|
||||
return '';
|
||||
|
||||
// selector points to no specific frame, highlight in all frames
|
||||
if (resolved?.frame === mainFrame)
|
||||
return stringifySelector(resolved.info.parsed);
|
||||
|
||||
// selector points to this frame, highlight it
|
||||
if (resolved?.frame === frame)
|
||||
return stringifySelector(resolved.info.parsed);
|
||||
|
||||
// selector points to a different frame, highlight nothing
|
||||
return '';
|
||||
} catch {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
setOutput(codegenId: string, outputFile: string | undefined) {
|
||||
this._contextRecorder.setOutput(codegenId, outputFile);
|
||||
}
|
||||
|
||||
private _refreshOverlay() {
|
||||
for (const page of this._context.pages())
|
||||
page.mainFrame().evaluateExpression('window.__pw_refreshOverlay()').catch(() => {});
|
||||
for (const page of this._context.pages()) {
|
||||
for (const frame of page.frames())
|
||||
frame.evaluateExpression('window.__pw_refreshOverlay()').catch(() => {});
|
||||
}
|
||||
}
|
||||
|
||||
async onBeforeCall(sdkObject: SdkObject, metadata: CallMetadata) {
|
||||
|
|
|
@ -253,3 +253,29 @@ test('should reset routes before reuse', async ({ server, connectedBrowserFactor
|
|||
await expect(page2).toHaveTitle('console.log test');
|
||||
await browser2.close();
|
||||
});
|
||||
|
||||
test('should highlight inside iframe', async ({ backend, connectedBrowser }, testInfo) => {
|
||||
testInfo.annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/33146' });
|
||||
|
||||
const context = await connectedBrowser._newContextForReuse();
|
||||
const page = await context.newPage();
|
||||
await backend.navigate({ url: `data:text/html,<div>bar</div><iframe srcdoc="<div>bar</div>"/>` });
|
||||
|
||||
|
||||
await page.frameLocator('iframe').getByText('bar').highlight();
|
||||
|
||||
const highlight = page.frameLocator('iframe').locator('x-pw-highlight');
|
||||
await expect(highlight).not.toHaveCount(0);
|
||||
await backend.hideHighlight();
|
||||
await expect(highlight).toHaveCount(0);
|
||||
|
||||
await backend.highlight({ selector: `frameLocator('iframe').getByText('bar')` });
|
||||
await expect(highlight).not.toHaveCount(0);
|
||||
|
||||
await backend.highlight({ selector: `frameLocator('iframe').frameLocator('iframe').getByText('bar')` });
|
||||
await expect(highlight).toHaveCount(0);
|
||||
|
||||
await backend.highlight({ selector: `getByText('bar')` });
|
||||
await expect(highlight).toHaveCount(1);
|
||||
await expect(page.locator('x-pw-highlight')).toHaveCount(1);
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue