From 6d7d37061d32280160894ef8d6d1fced1ff58775 Mon Sep 17 00:00:00 2001 From: Max Schmitt Date: Sun, 22 Oct 2023 13:02:14 +0200 Subject: [PATCH] fix(recorder): Locator picker had wrong initial language in language bindings (#27706) **Description** When a language port was using Inspector with the "Locator Picker" feature, it only recognised JavaScript as a language by default. As a workaround the user was able to click record, interact with the page and then the language would be correctly used -> csharp e.g. would work in the "Locator Picker". **Why?** Our language bindings are setting `PW_LANG_NAME=` env var -> good. Our recorder harness also uses this along its internal state here: https://github.com/microsoft/playwright/blob/b9b289b6415515b1b8e1a2524ed6425c8992af5a/packages/playwright-core/src/server/recorder.ts#L369 and it gets used here (no parameter means: we use the first language aka. primary language): https://github.com/microsoft/playwright/blob/b9b289b6415515b1b8e1a2524ed6425c8992af5a/packages/playwright-core/src/server/recorder.ts#L95 The only issue is that the Inspector frontend in the beginning does not know which language it should use and pass over to the server side, it then falls back to JavaScript. **Proposed fix** Instead of passing it over from the frontend to the server side, we just always use it from the server side, aka. "currentLanguage". When the user switches languages in the frontend, "currentLanguage" already gets updated properly via the "fileChanged" event. https://github.com/microsoft/playwright-dotnet/issues/2718 --------- Signed-off-by: Max Schmitt --- .../playwright-core/src/server/recorder.ts | 9 ++++--- packages/recorder/src/recorder.tsx | 9 +++---- tests/library/inspector/pause.spec.ts | 25 +++++++++++++++++++ 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/packages/playwright-core/src/server/recorder.ts b/packages/playwright-core/src/server/recorder.ts index 0d8ce496fd..6930610f38 100644 --- a/packages/playwright-core/src/server/recorder.ts +++ b/packages/playwright-core/src/server/recorder.ts @@ -36,7 +36,7 @@ import { RecorderApp } from './recorder/recorderApp'; import type { CallMetadata, InstrumentationListener, SdkObject } from './instrumentation'; import type { Point } from '../common/types'; import type { CallLog, CallLogStatus, EventData, Mode, Source, UIState } from '@recorder/recorderTypes'; -import { createGuid, monotonicTime } from '../utils'; +import { createGuid, isUnderTest, monotonicTime } from '../utils'; import { metadataToCallLog } from './recorder/recorderUtils'; import { Debugger } from './debugger'; import { EventEmitter } from 'events'; @@ -71,7 +71,10 @@ export class Recorder implements InstrumentationListener { } static showInspector(context: BrowserContext) { - Recorder.show(context, {}).catch(() => {}); + const params: channels.BrowserContextRecorderSupplementEnableParams = {}; + if (isUnderTest()) + params.language = process.env.TEST_INSPECTOR_LANGUAGE; + Recorder.show(context, params).catch(() => {}); } static show(context: BrowserContext, params: channels.BrowserContextRecorderSupplementEnableParams = {}): Promise { @@ -114,7 +117,7 @@ export class Recorder implements InstrumentationListener { return; } if (data.event === 'selectorUpdated') { - this.setHighlightedSelector(data.params.language, data.params.selector); + this.setHighlightedSelector(this._currentLanguage, data.params.selector); return; } if (data.event === 'step') { diff --git a/packages/recorder/src/recorder.tsx b/packages/recorder/src/recorder.tsx index af32c60d0b..7d269d0367 100644 --- a/packages/recorder/src/recorder.tsx +++ b/packages/recorder/src/recorder.tsx @@ -106,11 +106,10 @@ export const Recorder: React.FC = ({ return () => document.removeEventListener('keydown', handleKeyDown); }, [paused]); - const onEditorChange = React.useCallback((text: string) => { - setLocator(text); - const source = sources.find(s => s.id === fileId); - window.dispatch({ event: 'selectorUpdated', params: { selector: text, language: source?.language || 'javascript' } }); - }, [sources, fileId]); + const onEditorChange = React.useCallback((selector: string) => { + setLocator(selector); + window.dispatch({ event: 'selectorUpdated', params: { selector } }); + }, []); return
diff --git a/tests/library/inspector/pause.spec.ts b/tests/library/inspector/pause.spec.ts index 81147a2dd9..bb5c23c1ce 100644 --- a/tests/library/inspector/pause.spec.ts +++ b/tests/library/inspector/pause.spec.ts @@ -397,6 +397,31 @@ it.describe('pause', () => { await scriptPromise; }); + it('should highlight on explore (csharp)', async ({ page, recorderPageGetter }) => { + process.env.TEST_INSPECTOR_LANGUAGE = 'csharp'; + try { + await page.setContent(''); + const scriptPromise = (async () => { + await page.pause(); + })(); + const recorderPage = await recorderPageGetter(); + + const box1Promise = waitForTestLog(page, 'Highlight box for test: '); + await recorderPage.getByText('Locator', { exact: true }).click(); + await recorderPage.locator('.tabbed-pane .CodeMirror').click(); + await recorderPage.keyboard.type('GetByText("Submit")'); + const box1 = await box1Promise; + + const button = await page.$('text=Submit'); + const box2 = await button.boundingBox(); + expect(roundBox(box1)).toEqual(roundBox(box2)); + await recorderPage.click('[title="Resume (F8)"]'); + await scriptPromise; + } finally { + delete process.env.TEST_INSPECTOR_LANGUAGE; + } + }); + it('should not prevent key events', async ({ page, recorderPageGetter }) => { await page.setContent('
Hello
'); await page.evaluate(() => {