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=<sdkLanguage>` env var
-> good. Our recorder harness also uses this along its internal state
here:


b9b289b641/packages/playwright-core/src/server/recorder.ts (L369)

and it gets used here (no parameter means: we use the first language
aka. primary language):


b9b289b641/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 <max@schmitt.mx>
This commit is contained in:
Max Schmitt 2023-10-22 13:02:14 +02:00 committed by GitHub
parent d1d5fc67dc
commit 6d7d37061d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 35 additions and 8 deletions

View File

@ -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<Recorder> {
@ -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') {

View File

@ -106,11 +106,10 @@ export const Recorder: React.FC<RecorderProps> = ({
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 <div className='recorder'>
<Toolbar>

View File

@ -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('<button>Submit</button>');
const scriptPromise = (async () => {
await page.pause();
})();
const recorderPage = await recorderPageGetter();
const box1Promise = waitForTestLog<Box>(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('<div>Hello</div>');
await page.evaluate(() => {