Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/cli/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ commandWithOpenOptions('open [url]', 'open page in browser specified via -b, --b
commandWithOpenOptions('codegen [url]', 'open page and generate code for user actions',
[
['-o, --output <file name>', 'saves the generated script to a file'],
['--target <language>', `language to use, one of javascript, python, python-async, csharp`, language()],
['--target <language>', `language to generate, one of javascript, test, python, python-async, csharp`, language()],
]).action(function(url, command) {
codegen(command, url, command.target, command.output).catch(logErrorAndExit);
}).on('--help', function() {
Expand Down Expand Up @@ -554,7 +554,7 @@ function logErrorAndExit(e: Error) {
}

function language(): string {
return process.env.PW_CLI_TARGET_LANG || 'javascript';
return process.env.PW_CLI_TARGET_LANG || 'test';
}

function commandWithOpenOptions(command: string, description: string, options: any[][]): program.Command {
Expand Down
7 changes: 5 additions & 2 deletions src/server/supplements/recorder/codeGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,11 @@ export class CodeGenerator extends EventEmitter {
const text = [];
if (this._options.generateHeaders)
text.push(languageGenerator.generateHeader(this._options));
for (const action of this._actions)
text.push(languageGenerator.generateAction(action));
for (const action of this._actions) {
const actionText = languageGenerator.generateAction(action);
Comment thread
pavelfeldman marked this conversation as resolved.
if (actionText)
text.push(actionText);
}
if (this._options.generateHeaders)
text.push(languageGenerator.generateFooter(this._options.saveStorage));
return text.join('\n');
Expand Down
2 changes: 1 addition & 1 deletion src/server/supplements/recorder/csharp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import deviceDescriptors from '../../deviceDescriptors';

export class CSharpLanguageGenerator implements LanguageGenerator {
id = 'csharp';
fileName = '<csharp>';
fileName = 'C#';
highlighter = 'csharp';

generateAction(actionInContext: ActionInContext): string {
Expand Down
2 changes: 1 addition & 1 deletion src/server/supplements/recorder/java.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { JavaScriptFormatter } from './javascript';

export class JavaLanguageGenerator implements LanguageGenerator {
id = 'java';
fileName = '<java>';
fileName = 'Java';
highlighter = 'java';

generateAction(actionInContext: ActionInContext): string {
Expand Down
49 changes: 44 additions & 5 deletions src/server/supplements/recorder/javascript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,16 @@ import { MouseClickOptions, toModifiers } from './utils';
import deviceDescriptors from '../../deviceDescriptors';

export class JavaScriptLanguageGenerator implements LanguageGenerator {
id = 'javascript';
fileName = '<javascript>';
id: string;
fileName: string;
highlighter = 'javascript';
private _isTest: boolean;

constructor(isTest: boolean) {
this.id = isTest ? 'test' : 'javascript';
this.fileName = isTest ? 'Playwright Test' : 'JavaScript';
this._isTest = isTest;
}

generateAction(actionInContext: ActionInContext): string {
const { action, pageAlias } = actionInContext;
Expand All @@ -33,6 +40,8 @@ export class JavaScriptLanguageGenerator implements LanguageGenerator {
formatter.add('// ' + actionTitle(action));

if (action.name === 'openPage') {
if (this._isTest)
return '';
formatter.add(`const ${pageAlias} = await context.newPage();`);
if (action.url && action.url !== 'about:blank' && action.url !== 'chrome://newtab/')
formatter.add(`await ${pageAlias}.goto(${quote(action.url)});`);
Expand Down Expand Up @@ -84,8 +93,12 @@ export class JavaScriptLanguageGenerator implements LanguageGenerator {

if (emitPromiseAll)
formatter.add(`]);`);
else if (signals.assertNavigation)
formatter.add(` // assert.equal(${pageAlias}.url(), ${quote(signals.assertNavigation.url)});`);
else if (signals.assertNavigation) {
if (this._isTest)
formatter.add(` expect(${pageAlias}.url()).toBe(${quote(signals.assertNavigation.url)});`);
else
formatter.add(` // assert.equal(${pageAlias}.url(), ${quote(signals.assertNavigation.url)});`);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe remove the asserts? We have tests with expect for people now.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I did it and then test started failing and i don't want to fix it for merge. Will follow up.

}
return formatter.format();
}

Expand Down Expand Up @@ -131,6 +144,32 @@ export class JavaScriptLanguageGenerator implements LanguageGenerator {
}

generateHeader(options: LanguageGeneratorOptions): string {
if (this._isTest)
return this.generateTestHeader(options);
return this.generateStandaloneHeader(options);
}

generateFooter(saveStorage: string | undefined): string {
if (this._isTest)
return this.generateTestFooter(saveStorage);
return this.generateStandaloneFooter(saveStorage);
}

generateTestHeader(options: LanguageGeneratorOptions): string {
const formatter = new JavaScriptFormatter();
const useText = formatContextOptions(options.contextOptions, options.deviceName);
formatter.add(`
const { test, expect${options.deviceName ? ', devices' : ''} } = require('@playwright/test');
${useText ? '\ntest.use(' + useText + ');\n' : ''}
test('test', async ({ page }) => {`);
return formatter.format();
}

generateTestFooter(saveStorage: string | undefined): string {
return `\n});`;
}

generateStandaloneHeader(options: LanguageGeneratorOptions): string {
const formatter = new JavaScriptFormatter();
formatter.add(`
const { ${options.browserName}${options.deviceName ? ', devices' : ''} } = require('playwright');
Expand All @@ -141,7 +180,7 @@ export class JavaScriptLanguageGenerator implements LanguageGenerator {
return formatter.format();
}

generateFooter(saveStorage: string | undefined): string {
generateStandaloneFooter(saveStorage: string | undefined): string {
const storageStateLine = saveStorage ? `\n await context.storageState({ path: '${saveStorage}' });` : '';
return `\n // ---------------------${storageStateLine}
await context.close();
Expand Down
4 changes: 2 additions & 2 deletions src/server/supplements/recorder/python.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import deviceDescriptors from '../../deviceDescriptors';

export class PythonLanguageGenerator implements LanguageGenerator {
id = 'python';
fileName = '<python>';
fileName = 'Python';
highlighter = 'python';

private _awaitPrefix: '' | 'await ';
Expand All @@ -32,7 +32,7 @@ export class PythonLanguageGenerator implements LanguageGenerator {

constructor(isAsync: boolean) {
this.id = isAsync ? 'python-async' : 'python';
this.fileName = isAsync ? '<async python>' : '<python>';
this.fileName = isAsync ? 'Python Async' : 'Python';
this._isAsync = isAsync;
this._awaitPrefix = isAsync ? 'await ' : '';
this._asyncPrefix = isAsync ? 'async ' : '';
Expand Down
3 changes: 2 additions & 1 deletion src/server/supplements/recorderSupplement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ export class RecorderSupplement implements InstrumentationListener {

const languages = new Set([
new JavaLanguageGenerator(),
new JavaScriptLanguageGenerator(),
new JavaScriptLanguageGenerator(false),
new JavaScriptLanguageGenerator(true),
new PythonLanguageGenerator(false),
new PythonLanguageGenerator(true),
new CSharpLanguageGenerator(),
Expand Down
2 changes: 1 addition & 1 deletion src/web/recorder/recorder.css
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
background: none;
outline: none;
color: var(--toolbar-color);
margin-left: 16px;
min-width: 100px;
}

.recorder .toolbar-button.toggled.microscope {
Expand Down
3 changes: 2 additions & 1 deletion src/web/recorder/recorder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ export const Recorder: React.FC<RecorderProps> = ({
<ToolbarButton icon='debug-step-over' title='Step over' disabled={!paused} onClick={() => {
window.dispatch({ event: 'step' });
}}></ToolbarButton>
<div style={{flex: 'auto'}}></div>
<div>Target:</div>
<select className='recorder-chooser' hidden={!sources.length} value={file} onChange={event => {
setFile(event.target.selectedOptions[0].value);
}}>{
Expand All @@ -104,7 +106,6 @@ export const Recorder: React.FC<RecorderProps> = ({
})
}
</select>
<div style={{flex: 'auto'}}></div>
<ToolbarButton icon='clear-all' title='Clear' disabled={!source || !source.text} onClick={() => {
window.dispatch({ event: 'clear' });
}}></ToolbarButton>
Expand Down
Loading