feat(codegen): allow generating tests (#7049)

This commit is contained in:
Pavel Feldman 2021-06-10 16:52:59 -07:00 committed by GitHub
parent ab4398e60a
commit 3b1bae8a40
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 344 additions and 202 deletions

View File

@ -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() {
@ -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 {

View File

@ -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);
if (actionText)
text.push(actionText);
}
if (this._options.generateHeaders)
text.push(languageGenerator.generateFooter(this._options.saveStorage));
return text.join('\n');

View File

@ -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 {

View File

@ -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 {

View File

@ -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;
@ -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)});`);
@ -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)});`);
}
return formatter.format();
}
@ -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');
@ -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();

View File

@ -23,7 +23,7 @@ import deviceDescriptors from '../../deviceDescriptors';
export class PythonLanguageGenerator implements LanguageGenerator {
id = 'python';
fileName = '<python>';
fileName = 'Python';
highlighter = 'python';
private _awaitPrefix: '' | 'await ';
@ -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 ' : '';

View File

@ -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(),

View File

@ -35,7 +35,7 @@
background: none;
outline: none;
color: var(--toolbar-color);
margin-left: 16px;
min-width: 100px;
}
.recorder .toolbar-button.toggled.microscope {

View File

@ -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);
}}>{
@ -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>

View File

@ -30,27 +30,27 @@ test.describe('cli codegen', () => {
const [message, sources] = await Promise.all([
page.waitForEvent('console', msg => msg.type() !== 'error'),
recorder.waitForOutput('<javascript>', 'click'),
recorder.waitForOutput('JavaScript', 'click'),
page.dispatchEvent('button', 'click', { detail: 1 })
]);
expect(sources.get('<javascript>').text).toContain(`
expect(sources.get('JavaScript').text).toContain(`
// Click text=Submit
await page.click('text=Submit');`);
expect(sources.get('<python>').text).toContain(`
expect(sources.get('Python').text).toContain(`
# Click text=Submit
page.click("text=Submit")`);
expect(sources.get('<async python>').text).toContain(`
expect(sources.get('Python Async').text).toContain(`
# Click text=Submit
await page.click("text=Submit")`);
expect(sources.get('<java>').text).toContain(`
expect(sources.get('Java').text).toContain(`
// Click text=Submit
page.click("text=Submit");`);
expect(sources.get('<csharp>').text).toContain(`
expect(sources.get('C#').text).toContain(`
// Click text=Submit
await page.ClickAsync("text=Submit");`);
@ -78,11 +78,11 @@ test.describe('cli codegen', () => {
const [message, sources] = await Promise.all([
page.waitForEvent('console', msg => msg.type() !== 'error'),
recorder.waitForOutput('<javascript>', 'click'),
recorder.waitForOutput('JavaScript', 'click'),
page.dispatchEvent('button', 'click', { detail: 1 })
]);
expect(sources.get('<javascript>').text).toContain(`
expect(sources.get('JavaScript').text).toContain(`
// Click text=Submit
await page.click('text=Submit');`);
expect(message.text()).toBe('click');
@ -104,27 +104,27 @@ test.describe('cli codegen', () => {
const [message, sources] = await Promise.all([
page.waitForEvent('console', msg => msg.type() !== 'error'),
recorder.waitForOutput('<javascript>', 'click'),
recorder.waitForOutput('JavaScript', 'click'),
page.dispatchEvent('button', 'click', { detail: 1 })
]);
expect(sources.get('<javascript>').text).toContain(`
expect(sources.get('JavaScript').text).toContain(`
// Click text=Submit
await page.click('text=Submit');`);
expect(sources.get('<python>').text).toContain(`
expect(sources.get('Python').text).toContain(`
# Click text=Submit
page.click("text=Submit")`);
expect(sources.get('<async python>').text).toContain(`
expect(sources.get('Python Async').text).toContain(`
# Click text=Submit
await page.click("text=Submit")`);
expect(sources.get('<java>').text).toContain(`
expect(sources.get('Java').text).toContain(`
// Click text=Submit
page.click("text=Submit");`);
expect(sources.get('<csharp>').text).toContain(`
expect(sources.get('C#').text).toContain(`
// Click text=Submit
await page.ClickAsync("text=Submit");`);
@ -156,10 +156,10 @@ test.describe('cli codegen', () => {
const [message, sources] = await Promise.all([
page.waitForEvent('console', msg => msg.type() !== 'error'),
recorder.waitForOutput('<javascript>', 'click'),
recorder.waitForOutput('JavaScript', 'click'),
page.dispatchEvent('div', 'click', { detail: 1 })
]);
expect(sources.get('<javascript>').text).toContain(`
expect(sources.get('JavaScript').text).toContain(`
// Click text=Some long text here
await page.click('text=Some long text here');`);
expect(message.text()).toBe('click');
@ -174,26 +174,26 @@ test.describe('cli codegen', () => {
const [message, sources] = await Promise.all([
page.waitForEvent('console', msg => msg.type() !== 'error'),
recorder.waitForOutput('<javascript>', 'fill'),
recorder.waitForOutput('JavaScript', 'fill'),
page.fill('input', 'John')
]);
expect(sources.get('<javascript>').text).toContain(`
expect(sources.get('JavaScript').text).toContain(`
// Fill input[name="name"]
await page.fill('input[name="name"]', 'John');`);
expect(sources.get('<java>').text).toContain(`
expect(sources.get('Java').text).toContain(`
// Fill input[name="name"]
page.fill("input[name=\\\"name\\\"]", "John");`);
expect(sources.get('<python>').text).toContain(`
expect(sources.get('Python').text).toContain(`
# Fill input[name="name"]
page.fill(\"input[name=\\\"name\\\"]\", \"John\")`);
expect(sources.get('<async python>').text).toContain(`
expect(sources.get('Python Async').text).toContain(`
# Fill input[name="name"]
await page.fill(\"input[name=\\\"name\\\"]\", \"John\")`);
expect(sources.get('<csharp>').text).toContain(`
expect(sources.get('C#').text).toContain(`
// Fill input[name="name"]
await page.FillAsync(\"input[name=\\\"name\\\"]\", \"John\");`);
@ -209,10 +209,10 @@ test.describe('cli codegen', () => {
const [message, sources] = await Promise.all([
page.waitForEvent('console', msg => msg.type() !== 'error'),
recorder.waitForOutput('<javascript>', 'fill'),
recorder.waitForOutput('JavaScript', 'fill'),
page.fill('textarea', 'John')
]);
expect(sources.get('<javascript>').text).toContain(`
expect(sources.get('JavaScript').text).toContain(`
// Fill textarea[name="name"]
await page.fill('textarea[name="name"]', 'John');`);
expect(message.text()).toBe('John');
@ -230,27 +230,27 @@ test.describe('cli codegen', () => {
page.on('console', message => messages.push(message));
const [, sources] = await Promise.all([
recorder.waitForActionPerformed(),
recorder.waitForOutput('<javascript>', 'press'),
recorder.waitForOutput('JavaScript', 'press'),
page.press('input', 'Shift+Enter')
]);
expect(sources.get('<javascript>').text).toContain(`
expect(sources.get('JavaScript').text).toContain(`
// Press Enter with modifiers
await page.press('input[name="name"]', 'Shift+Enter');`);
expect(sources.get('<java>').text).toContain(`
expect(sources.get('Java').text).toContain(`
// Press Enter with modifiers
page.press("input[name=\\\"name\\\"]", "Shift+Enter");`);
expect(sources.get('<python>').text).toContain(`
expect(sources.get('Python').text).toContain(`
# Press Enter with modifiers
page.press(\"input[name=\\\"name\\\"]\", \"Shift+Enter\")`);
expect(sources.get('<async python>').text).toContain(`
expect(sources.get('Python Async').text).toContain(`
# Press Enter with modifiers
await page.press(\"input[name=\\\"name\\\"]\", \"Shift+Enter\")`);
expect(sources.get('<csharp>').text).toContain(`
expect(sources.get('C#').text).toContain(`
// Press Enter with modifiers
await page.PressAsync(\"input[name=\\\"name\\\"]\", \"Shift+Enter\");`);
@ -266,16 +266,16 @@ test.describe('cli codegen', () => {
`);
await page.click('input[name="one"]');
await recorder.waitForOutput('<javascript>', 'click');
await recorder.waitForOutput('JavaScript', 'click');
await page.keyboard.type('foobar123');
await recorder.waitForOutput('<javascript>', 'foobar123');
await recorder.waitForOutput('JavaScript', 'foobar123');
await page.keyboard.press('Tab');
await recorder.waitForOutput('<javascript>', 'Tab');
await recorder.waitForOutput('JavaScript', 'Tab');
await page.keyboard.type('barfoo321');
await recorder.waitForOutput('<javascript>', 'barfoo321');
await recorder.waitForOutput('JavaScript', 'barfoo321');
const text = recorder.sources().get('<javascript>').text;
const text = recorder.sources().get('JavaScript').text;
expect(text).toContain(`
// Fill input[name="one"]
await page.fill('input[name="one"]', 'foobar123');`);
@ -303,10 +303,10 @@ test.describe('cli codegen', () => {
});
const [, sources] = await Promise.all([
recorder.waitForActionPerformed(),
recorder.waitForOutput('<javascript>', 'press'),
recorder.waitForOutput('JavaScript', 'press'),
page.press('input', 'ArrowDown')
]);
expect(sources.get('<javascript>').text).toContain(`
expect(sources.get('JavaScript').text).toContain(`
// Press ArrowDown
await page.press('input[name="name"]', 'ArrowDown');`);
expect(messages[0].text()).toBe('press:ArrowDown');
@ -327,10 +327,10 @@ test.describe('cli codegen', () => {
});
const [, sources] = await Promise.all([
recorder.waitForActionPerformed(),
recorder.waitForOutput('<javascript>', 'press'),
recorder.waitForOutput('JavaScript', 'press'),
page.press('input', 'ArrowDown')
]);
expect(sources.get('<javascript>').text).toContain(`
expect(sources.get('JavaScript').text).toContain(`
// Press ArrowDown
await page.press('input[name="name"]', 'ArrowDown');`);
expect(messages.length).toBe(2);
@ -348,27 +348,27 @@ test.describe('cli codegen', () => {
const [message, sources] = await Promise.all([
page.waitForEvent('console', msg => msg.type() !== 'error'),
recorder.waitForOutput('<javascript>', 'check'),
recorder.waitForOutput('JavaScript', 'check'),
page.click('input')
]);
expect(sources.get('<javascript>').text).toContain(`
expect(sources.get('JavaScript').text).toContain(`
// Check input[name="accept"]
await page.check('input[name="accept"]');`);
expect(sources.get('<java>').text).toContain(`
expect(sources.get('Java').text).toContain(`
// Check input[name="accept"]
page.check("input[name=\\\"accept\\\"]");`);
expect(sources.get('<python>').text).toContain(`
expect(sources.get('Python').text).toContain(`
# Check input[name="accept"]
page.check(\"input[name=\\\"accept\\\"]\")`);
expect(sources.get('<async python>').text).toContain(`
expect(sources.get('Python Async').text).toContain(`
# Check input[name="accept"]
await page.check(\"input[name=\\\"accept\\\"]\")`);
expect(sources.get('<csharp>').text).toContain(`
expect(sources.get('C#').text).toContain(`
// Check input[name="accept"]
await page.CheckAsync(\"input[name=\\\"accept\\\"]\");`);
@ -385,11 +385,11 @@ test.describe('cli codegen', () => {
const [message, sources] = await Promise.all([
page.waitForEvent('console', msg => msg.type() !== 'error'),
recorder.waitForOutput('<javascript>', 'check'),
recorder.waitForOutput('JavaScript', 'check'),
page.keyboard.press('Space')
]);
expect(sources.get('<javascript>').text).toContain(`
expect(sources.get('JavaScript').text).toContain(`
// Check input[name="accept"]
await page.check('input[name="accept"]');`);
expect(message.text()).toBe('true');
@ -405,27 +405,27 @@ test.describe('cli codegen', () => {
const [message, sources] = await Promise.all([
page.waitForEvent('console', msg => msg.type() !== 'error'),
recorder.waitForOutput('<javascript>', 'uncheck'),
recorder.waitForOutput('JavaScript', 'uncheck'),
page.click('input')
]);
expect(sources.get('<javascript>').text).toContain(`
expect(sources.get('JavaScript').text).toContain(`
// Uncheck input[name="accept"]
await page.uncheck('input[name="accept"]');`);
expect(sources.get('<java>').text).toContain(`
expect(sources.get('Java').text).toContain(`
// Uncheck input[name="accept"]
page.uncheck("input[name=\\\"accept\\\"]");`);
expect(sources.get('<python>').text).toContain(`
expect(sources.get('Python').text).toContain(`
# Uncheck input[name="accept"]
page.uncheck(\"input[name=\\\"accept\\\"]\")`);
expect(sources.get('<async python>').text).toContain(`
expect(sources.get('Python Async').text).toContain(`
# Uncheck input[name="accept"]
await page.uncheck(\"input[name=\\\"accept\\\"]\")`);
expect(sources.get('<csharp>').text).toContain(`
expect(sources.get('C#').text).toContain(`
// Uncheck input[name="accept"]
await page.UncheckAsync(\"input[name=\\\"accept\\\"]\");`);
@ -442,27 +442,27 @@ test.describe('cli codegen', () => {
const [message, sources] = await Promise.all([
page.waitForEvent('console', msg => msg.type() !== 'error'),
recorder.waitForOutput('<javascript>', 'select'),
recorder.waitForOutput('JavaScript', 'select'),
page.selectOption('select', '2')
]);
expect(sources.get('<javascript>').text).toContain(`
expect(sources.get('JavaScript').text).toContain(`
// Select 2
await page.selectOption('select', '2');`);
expect(sources.get('<java>').text).toContain(`
expect(sources.get('Java').text).toContain(`
// Select 2
page.selectOption("select", "2");`);
expect(sources.get('<python>').text).toContain(`
expect(sources.get('Python').text).toContain(`
# Select 2
page.select_option(\"select\", \"2\")`);
expect(sources.get('<async python>').text).toContain(`
expect(sources.get('Python Async').text).toContain(`
# Select 2
await page.select_option(\"select\", \"2\")`);
expect(sources.get('<csharp>').text).toContain(`
expect(sources.get('C#').text).toContain(`
// Select 2
await page.SelectOptionAsync(\"select\", new[] { \"2\" });`);
@ -480,36 +480,36 @@ test.describe('cli codegen', () => {
const [popup, sources] = await Promise.all([
page.context().waitForEvent('page'),
recorder.waitForOutput('<javascript>', 'waitForEvent'),
recorder.waitForOutput('JavaScript', 'waitForEvent'),
page.dispatchEvent('a', 'click', { detail: 1 })
]);
expect(sources.get('<javascript>').text).toContain(`
expect(sources.get('JavaScript').text).toContain(`
// Click text=link
const [page1] = await Promise.all([
page.waitForEvent('popup'),
page.click('text=link')
]);`);
expect(sources.get('<java>').text).toContain(`
expect(sources.get('Java').text).toContain(`
// Click text=link
Page page1 = page.waitForPopup(() -> {
page.click("text=link");
});`);
expect(sources.get('<python>').text).toContain(`
expect(sources.get('Python').text).toContain(`
# Click text=link
with page.expect_popup() as popup_info:
page.click(\"text=link\")
page1 = popup_info.value`);
expect(sources.get('<async python>').text).toContain(`
expect(sources.get('Python Async').text).toContain(`
# Click text=link
async with page.expect_popup() as popup_info:
await page.click(\"text=link\")
page1 = await popup_info.value`);
expect(sources.get('<csharp>').text).toContain(`
expect(sources.get('C#').text).toContain(`
var page1 = await page.RunAndWaitForPopupAsync(async () =>
{
await page.ClickAsync(\"text=link\");
@ -527,31 +527,36 @@ test.describe('cli codegen', () => {
expect(selector).toBe('text=link');
const [, sources] = await Promise.all([
page.waitForNavigation(),
recorder.waitForOutput('<javascript>', 'assert'),
recorder.waitForOutput('JavaScript', 'assert'),
page.dispatchEvent('a', 'click', { detail: 1 })
]);
expect(sources.get('<javascript>').text).toContain(`
expect(sources.get('JavaScript').text).toContain(`
// Click text=link
await page.click('text=link');
// assert.equal(page.url(), 'about:blank#foo');`);
expect(sources.get('<java>').text).toContain(`
expect(sources.get('Playwright Test').text).toContain(`
// Click text=link
await page.click('text=link');
expect(page.url()).toBe('about:blank#foo');`);
expect(sources.get('Java').text).toContain(`
// Click text=link
page.click("text=link");
// assert page.url().equals("about:blank#foo");`);
expect(sources.get('<python>').text).toContain(`
expect(sources.get('Python').text).toContain(`
# Click text=link
page.click(\"text=link\")
# assert page.url == \"about:blank#foo\"`);
expect(sources.get('<async python>').text).toContain(`
expect(sources.get('Python Async').text).toContain(`
# Click text=link
await page.click(\"text=link\")
# assert page.url == \"about:blank#foo\"`);
expect(sources.get('<csharp>').text).toContain(`
expect(sources.get('C#').text).toContain(`
// Click text=link
await page.ClickAsync(\"text=link\");
// Assert.Equal(\"about:blank#foo\", page.Url);`);
@ -570,37 +575,37 @@ test.describe('cli codegen', () => {
const [, sources] = await Promise.all([
page.waitForNavigation(),
recorder.waitForOutput('<javascript>', 'waitForNavigation'),
recorder.waitForOutput('JavaScript', 'waitForNavigation'),
page.dispatchEvent('a', 'click', { detail: 1 })
]);
expect(sources.get('<javascript>').text).toContain(`
expect(sources.get('JavaScript').text).toContain(`
// Click text=link
await Promise.all([
page.waitForNavigation(/*{ url: 'about:blank#foo' }*/),
page.click('text=link')
]);`);
expect(sources.get('<java>').text).toContain(`
expect(sources.get('Java').text).toContain(`
// Click text=link
// page.waitForNavigation(new Page.WaitForNavigationOptions().setUrl("about:blank#foo"), () ->
page.waitForNavigation(() -> {
page.click("text=link");
});`);
expect(sources.get('<python>').text).toContain(`
expect(sources.get('Python').text).toContain(`
# Click text=link
# with page.expect_navigation(url=\"about:blank#foo\"):
with page.expect_navigation():
page.click(\"text=link\")`);
expect(sources.get('<async python>').text).toContain(`
expect(sources.get('Python Async').text).toContain(`
# Click text=link
# async with page.expect_navigation(url=\"about:blank#foo\"):
async with page.expect_navigation():
await page.click(\"text=link\")`);
expect(sources.get('<csharp>').text).toContain(`
expect(sources.get('C#').text).toContain(`
// Click text=link
await page.RunAndWaitForNavigationAsync(async () =>
{
@ -622,9 +627,9 @@ test.describe('cli codegen', () => {
await recorder.page.keyboard.press('AltGraph');
await recorder.page.keyboard.insertText('@');
await recorder.page.keyboard.type('example.com');
await recorder.waitForOutput('<javascript>', 'example.com');
expect(recorder.sources().get('<javascript>').text).not.toContain(`await page.press('input', 'AltGraph');`);
expect(recorder.sources().get('<javascript>').text).toContain(`await page.fill('input', 'playwright@example.com');`);
await recorder.waitForOutput('JavaScript', 'example.com');
expect(recorder.sources().get('JavaScript').text).not.toContain(`await page.press('input', 'AltGraph');`);
expect(recorder.sources().get('JavaScript').text).toContain(`await page.fill('input', 'playwright@example.com');`);
});
test('should middle click', async ({ page, openRecorder, server }) => {
@ -633,26 +638,26 @@ test.describe('cli codegen', () => {
await recorder.setContentAndWait(`<a href${JSON.stringify(server.EMPTY_PAGE)}>Click me</a>`);
const [sources] = await Promise.all([
recorder.waitForOutput('<javascript>', 'click'),
recorder.waitForOutput('JavaScript', 'click'),
page.click('a', { button: 'middle' }),
]);
expect(sources.get('<javascript>').text).toContain(`
expect(sources.get('JavaScript').text).toContain(`
await page.click('text=Click me', {
button: 'middle'
});`);
expect(sources.get('<python>').text).toContain(`
expect(sources.get('Python').text).toContain(`
page.click("text=Click me", button="middle")`);
expect(sources.get('<async python>').text).toContain(`
expect(sources.get('Python Async').text).toContain(`
await page.click("text=Click me", button="middle")`);
expect(sources.get('<java>').text).toContain(`
expect(sources.get('Java').text).toContain(`
page.click("text=Click me", new Page.ClickOptions()
.setButton(MouseButton.MIDDLE));`);
expect(sources.get('<csharp>').text).toContain(`
expect(sources.get('C#').text).toContain(`
await page.ClickAsync("text=Click me", new PageClickOptions
{
Button = MouseButton.Middle,

View File

@ -24,25 +24,25 @@ test.describe('cli codegen', () => {
const recorder = await openRecorder();
await recorder.setContentAndWait(``);
const sources = await recorder.waitForOutput('<javascript>', `page.goto`);
const sources = await recorder.waitForOutput('JavaScript', `page.goto`);
expect(sources.get('<javascript>').text).toContain(`
expect(sources.get('JavaScript').text).toContain(`
// Open new page
const page = await context.newPage();`);
expect(sources.get('<java>').text).toContain(`
expect(sources.get('Java').text).toContain(`
// Open new page
Page page = context.newPage();`);
expect(sources.get('<python>').text).toContain(`
expect(sources.get('Python').text).toContain(`
# Open new page
page = context.new_page()`);
expect(sources.get('<async python>').text).toContain(`
expect(sources.get('Python Async').text).toContain(`
# Open new page
page = await context.new_page()`);
expect(sources.get('<csharp>').text).toContain(`
expect(sources.get('C#').text).toContain(`
// Open new page
var page = await context.NewPageAsync();`);
});
@ -52,25 +52,25 @@ test.describe('cli codegen', () => {
await recorder.setContentAndWait(``);
await page.context().newPage();
const sources = await recorder.waitForOutput('<javascript>', 'page1');
const sources = await recorder.waitForOutput('JavaScript', 'page1');
expect(sources.get('<javascript>').text).toContain(`
expect(sources.get('JavaScript').text).toContain(`
// Open new page
const page1 = await context.newPage();`);
expect(sources.get('<java>').text).toContain(`
expect(sources.get('Java').text).toContain(`
// Open new page
Page page1 = context.newPage();`);
expect(sources.get('<python>').text).toContain(`
expect(sources.get('Python').text).toContain(`
# Open new page
page1 = context.new_page()`);
expect(sources.get('<async python>').text).toContain(`
expect(sources.get('Python Async').text).toContain(`
# Open new page
page1 = await context.new_page()`);
expect(sources.get('<csharp>').text).toContain(`
expect(sources.get('C#').text).toContain(`
// Open new page
var page1 = await context.NewPageAsync();`);
});
@ -81,21 +81,21 @@ test.describe('cli codegen', () => {
await recorder.setContentAndWait(``);
await page.context().newPage();
await recorder.page.close();
const sources = await recorder.waitForOutput('<javascript>', 'page.close();');
const sources = await recorder.waitForOutput('JavaScript', 'page.close();');
expect(sources.get('<javascript>').text).toContain(`
expect(sources.get('JavaScript').text).toContain(`
await page.close();`);
expect(sources.get('<java>').text).toContain(`
expect(sources.get('Java').text).toContain(`
page.close();`);
expect(sources.get('<python>').text).toContain(`
expect(sources.get('Python').text).toContain(`
page.close()`);
expect(sources.get('<async python>').text).toContain(`
expect(sources.get('Python Async').text).toContain(`
await page.close()`);
expect(sources.get('<csharp>').text).toContain(`
expect(sources.get('C#').text).toContain(`
await page.CloseAsync();`);
});
@ -110,7 +110,7 @@ test.describe('cli codegen', () => {
const selector = await recorder.hoverOverElement('html');
expect(selector).toBe('html');
await recorder.page.close();
await recorder.waitForOutput('<javascript>', 'page.close();');
await recorder.waitForOutput('JavaScript', 'page.close();');
expect(errors.length).toBe(0);
});
@ -128,25 +128,25 @@ test.describe('cli codegen', () => {
await page.setInputFiles('input[type=file]', asset('file-to-upload.txt'));
await page.click('input[type=file]');
const sources = await recorder.waitForOutput('<javascript>', 'setInputFiles');
const sources = await recorder.waitForOutput('JavaScript', 'setInputFiles');
expect(sources.get('<javascript>').text).toContain(`
expect(sources.get('JavaScript').text).toContain(`
// Upload file-to-upload.txt
await page.setInputFiles('input[type="file"]', 'file-to-upload.txt');`);
expect(sources.get('<java>').text).toContain(`
expect(sources.get('Java').text).toContain(`
// Upload file-to-upload.txt
page.setInputFiles("input[type=\\\"file\\\"]", Paths.get("file-to-upload.txt"));`);
expect(sources.get('<python>').text).toContain(`
expect(sources.get('Python').text).toContain(`
# Upload file-to-upload.txt
page.set_input_files(\"input[type=\\\"file\\\"]\", \"file-to-upload.txt\")`);
expect(sources.get('<async python>').text).toContain(`
expect(sources.get('Python Async').text).toContain(`
# Upload file-to-upload.txt
await page.set_input_files(\"input[type=\\\"file\\\"]\", \"file-to-upload.txt\")`);
expect(sources.get('<csharp>').text).toContain(`
expect(sources.get('C#').text).toContain(`
// Upload file-to-upload.txt
await page.SetInputFilesAsync(\"input[type=\\\"file\\\"]\", new[] { \"file-to-upload.txt\" });`);
});
@ -165,25 +165,25 @@ test.describe('cli codegen', () => {
await page.setInputFiles('input[type=file]', [asset('file-to-upload.txt'), asset('file-to-upload-2.txt')]);
await page.click('input[type=file]');
const sources = await recorder.waitForOutput('<javascript>', 'setInputFiles');
const sources = await recorder.waitForOutput('JavaScript', 'setInputFiles');
expect(sources.get('<javascript>').text).toContain(`
expect(sources.get('JavaScript').text).toContain(`
// Upload file-to-upload.txt, file-to-upload-2.txt
await page.setInputFiles('input[type=\"file\"]', ['file-to-upload.txt', 'file-to-upload-2.txt']);`);
expect(sources.get('<java>').text).toContain(`
expect(sources.get('Java').text).toContain(`
// Upload file-to-upload.txt, file-to-upload-2.txt
page.setInputFiles("input[type=\\\"file\\\"]", new Path[] {Paths.get("file-to-upload.txt"), Paths.get("file-to-upload-2.txt")});`);
expect(sources.get('<python>').text).toContain(`
expect(sources.get('Python').text).toContain(`
# Upload file-to-upload.txt, file-to-upload-2.txt
page.set_input_files(\"input[type=\\\"file\\\"]\", [\"file-to-upload.txt\", \"file-to-upload-2.txt\"]`);
expect(sources.get('<async python>').text).toContain(`
expect(sources.get('Python Async').text).toContain(`
# Upload file-to-upload.txt, file-to-upload-2.txt
await page.set_input_files(\"input[type=\\\"file\\\"]\", [\"file-to-upload.txt\", \"file-to-upload-2.txt\"]`);
expect(sources.get('<csharp>').text).toContain(`
expect(sources.get('C#').text).toContain(`
// Upload file-to-upload.txt, file-to-upload-2.txt
await page.SetInputFilesAsync(\"input[type=\\\"file\\\"]\", new[] { \"file-to-upload.txt\", \"file-to-upload-2.txt\" });`);
});
@ -202,25 +202,25 @@ test.describe('cli codegen', () => {
await page.setInputFiles('input[type=file]', []);
await page.click('input[type=file]');
const sources = await recorder.waitForOutput('<javascript>', 'setInputFiles');
const sources = await recorder.waitForOutput('JavaScript', 'setInputFiles');
expect(sources.get('<javascript>').text).toContain(`
expect(sources.get('JavaScript').text).toContain(`
// Clear selected files
await page.setInputFiles('input[type=\"file\"]', []);`);
expect(sources.get('<java>').text).toContain(`
expect(sources.get('Java').text).toContain(`
// Clear selected files
page.setInputFiles("input[type=\\\"file\\\"]", new Path[0]);`);
expect(sources.get('<python>').text).toContain(`
expect(sources.get('Python').text).toContain(`
# Clear selected files
page.set_input_files(\"input[type=\\\"file\\\"]\", []`);
expect(sources.get('<async python>').text).toContain(`
expect(sources.get('Python Async').text).toContain(`
# Clear selected files
await page.set_input_files(\"input[type=\\\"file\\\"]\", []`);
expect(sources.get('<csharp>').text).toContain(`
expect(sources.get('C#').text).toContain(`
// Clear selected files
await page.SetInputFilesAsync(\"input[type=\\\"file\\\"]\", new[] { });`);
@ -248,50 +248,50 @@ test.describe('cli codegen', () => {
page.waitForEvent('download'),
page.click('text=Download')
]);
const sources = await recorder.waitForOutput('<javascript>', 'waitForEvent');
const sources = await recorder.waitForOutput('JavaScript', 'waitForEvent');
expect(sources.get('<javascript>').text).toContain(`
expect(sources.get('JavaScript').text).toContain(`
const context = await browser.newContext({
acceptDownloads: true
});`);
expect(sources.get('<javascript>').text).toContain(`
expect(sources.get('JavaScript').text).toContain(`
// Click text=Download
const [download] = await Promise.all([
page.waitForEvent('download'),
page.click('text=Download')
]);`);
expect(sources.get('<java>').text).toContain(`
expect(sources.get('Java').text).toContain(`
BrowserContext context = browser.newContext(new Browser.NewContextOptions()
.setAcceptDownloads(true));`);
expect(sources.get('<java>').text).toContain(`
expect(sources.get('Java').text).toContain(`
// Click text=Download
Download download = page.waitForDownload(() -> {
page.click("text=Download");
});`);
expect(sources.get('<python>').text).toContain(`
expect(sources.get('Python').text).toContain(`
context = browser.new_context(accept_downloads=True)`);
expect(sources.get('<python>').text).toContain(`
expect(sources.get('Python').text).toContain(`
# Click text=Download
with page.expect_download() as download_info:
page.click(\"text=Download\")
download = download_info.value`);
expect(sources.get('<async python>').text).toContain(`
expect(sources.get('Python Async').text).toContain(`
context = await browser.new_context(accept_downloads=True)`);
expect(sources.get('<async python>').text).toContain(`
expect(sources.get('Python Async').text).toContain(`
# Click text=Download
async with page.expect_download() as download_info:
await page.click(\"text=Download\")
download = await download_info.value`);
expect(sources.get('<csharp>').text).toContain(`
expect(sources.get('C#').text).toContain(`
var context = await browser.NewContextAsync(new BrowserNewContextOptions
{
AcceptDownloads = true,
});`);
expect(sources.get('<csharp>').text).toContain(`
expect(sources.get('C#').text).toContain(`
// Click text=Download
var download1 = await page.RunAndWaitForDownloadAsync(async () =>
{
@ -311,9 +311,9 @@ test.describe('cli codegen', () => {
});
await page.click('text=click me');
const sources = await recorder.waitForOutput('<javascript>', 'once');
const sources = await recorder.waitForOutput('JavaScript', 'once');
expect(sources.get('<javascript>').text).toContain(`
expect(sources.get('JavaScript').text).toContain(`
// Click text=click me
page.once('dialog', dialog => {
console.log(\`Dialog message: \${dialog.message()}\`);
@ -321,7 +321,7 @@ test.describe('cli codegen', () => {
});
await page.click('text=click me');`);
expect(sources.get('<java>').text).toContain(`
expect(sources.get('Java').text).toContain(`
// Click text=click me
page.onceDialog(dialog -> {
System.out.println(String.format("Dialog message: %s", dialog.message()));
@ -329,17 +329,17 @@ test.describe('cli codegen', () => {
});
page.click("text=click me");`);
expect(sources.get('<python>').text).toContain(`
expect(sources.get('Python').text).toContain(`
# Click text=click me
page.once(\"dialog\", lambda dialog: dialog.dismiss())
page.click(\"text=click me\")`);
expect(sources.get('<async python>').text).toContain(`
expect(sources.get('Python Async').text).toContain(`
# Click text=click me
page.once(\"dialog\", lambda dialog: dialog.dismiss())
await page.click(\"text=click me\")`);
expect(sources.get('<csharp>').text).toContain(`
expect(sources.get('C#').text).toContain(`
// Click text=click me
void page_Dialog1_EventHandler(object sender, IDialog dialog)
{
@ -364,7 +364,7 @@ test.describe('cli codegen', () => {
</script>`, server.PREFIX);
for (let i = 1; i < 3; ++i) {
await page.evaluate('pushState()');
await recorder.waitForOutput('<javascript>', `await page.goto('${server.PREFIX}/#seqNum=${i}');`);
await recorder.waitForOutput('JavaScript', `await page.goto('${server.PREFIX}/#seqNum=${i}');`);
}
});
@ -378,23 +378,23 @@ test.describe('cli codegen', () => {
expect(selector).toBe('text=link');
await page.click('a', { modifiers: [ platform === 'darwin' ? 'Meta' : 'Control'] });
const sources = await recorder.waitForOutput('<javascript>', 'page1');
const sources = await recorder.waitForOutput('JavaScript', 'page1');
if (browserName === 'chromium') {
expect(sources.get('<javascript>').text).toContain(`
expect(sources.get('JavaScript').text).toContain(`
// Open new page
const page1 = await context.newPage();
await page1.goto('about:blank?foo');`);
expect(sources.get('<async python>').text).toContain(`
expect(sources.get('Python Async').text).toContain(`
# Open new page
page1 = await context.new_page()
await page1.goto("about:blank?foo")`);
expect(sources.get('<csharp>').text).toContain(`
expect(sources.get('C#').text).toContain(`
// Open new page
var page1 = await context.NewPageAsync();
await page1.GotoAsync("about:blank?foo");`);
} else if (browserName === 'firefox') {
expect(sources.get('<javascript>').text).toContain(`
expect(sources.get('JavaScript').text).toContain(`
// Click text=link
const [page1] = await Promise.all([
page.waitForEvent('popup'),
@ -422,26 +422,26 @@ test.describe('cli codegen', () => {
await recorder.setPageContentAndWait(popup2, '<input id=name>');
await popup1.type('input', 'TextA');
await recorder.waitForOutput('<javascript>', 'TextA');
await recorder.waitForOutput('JavaScript', 'TextA');
await popup2.type('input', 'TextB');
await recorder.waitForOutput('<javascript>', 'TextB');
await recorder.waitForOutput('JavaScript', 'TextB');
const sources = recorder.sources();
expect(sources.get('<javascript>').text).toContain(`await page1.fill('input', 'TextA');`);
expect(sources.get('<javascript>').text).toContain(`await page2.fill('input', 'TextB');`);
expect(sources.get('JavaScript').text).toContain(`await page1.fill('input', 'TextA');`);
expect(sources.get('JavaScript').text).toContain(`await page2.fill('input', 'TextB');`);
expect(sources.get('<java>').text).toContain(`page1.fill("input", "TextA");`);
expect(sources.get('<java>').text).toContain(`page2.fill("input", "TextB");`);
expect(sources.get('Java').text).toContain(`page1.fill("input", "TextA");`);
expect(sources.get('Java').text).toContain(`page2.fill("input", "TextB");`);
expect(sources.get('<python>').text).toContain(`page1.fill(\"input\", \"TextA\")`);
expect(sources.get('<python>').text).toContain(`page2.fill(\"input\", \"TextB\")`);
expect(sources.get('Python').text).toContain(`page1.fill(\"input\", \"TextA\")`);
expect(sources.get('Python').text).toContain(`page2.fill(\"input\", \"TextB\")`);
expect(sources.get('<async python>').text).toContain(`await page1.fill(\"input\", \"TextA\")`);
expect(sources.get('<async python>').text).toContain(`await page2.fill(\"input\", \"TextB\")`);
expect(sources.get('Python Async').text).toContain(`await page1.fill(\"input\", \"TextA\")`);
expect(sources.get('Python Async').text).toContain(`await page2.fill(\"input\", \"TextB\")`);
expect(sources.get('<csharp>').text).toContain(`await page1.FillAsync(\"input\", \"TextA\");`);
expect(sources.get('<csharp>').text).toContain(`await page2.FillAsync(\"input\", \"TextB\");`);
expect(sources.get('C#').text).toContain(`await page1.FillAsync(\"input\", \"TextA\");`);
expect(sources.get('C#').text).toContain(`await page2.FillAsync(\"input\", \"TextB\");`);
});
test('click should emit events in order', async ({ page, openRecorder }) => {
@ -463,7 +463,7 @@ test.describe('cli codegen', () => {
});
await Promise.all([
page.click('button'),
recorder.waitForOutput('<javascript>', 'page.click')
recorder.waitForOutput('JavaScript', 'page.click')
]);
expect(messages).toEqual(['mousedown', 'mouseup', 'click']);
});
@ -513,83 +513,83 @@ test.describe('cli codegen', () => {
const otherFrame = page.frames().find(f => f !== page.mainFrame() && !f.name());
let [sources] = await Promise.all([
recorder.waitForOutput('<javascript>', 'one'),
recorder.waitForOutput('JavaScript', 'one'),
frameOne.click('div'),
]);
expect(sources.get('<javascript>').text).toContain(`
expect(sources.get('JavaScript').text).toContain(`
// Click text=Hi, I'm frame
await page.frame({
name: 'one'
}).click('text=Hi, I\\'m frame');`);
expect(sources.get('<java>').text).toContain(`
expect(sources.get('Java').text).toContain(`
// Click text=Hi, I'm frame
page.frame("one").click("text=Hi, I'm frame");`);
expect(sources.get('<python>').text).toContain(`
expect(sources.get('Python').text).toContain(`
# Click text=Hi, I'm frame
page.frame(name=\"one\").click(\"text=Hi, I'm frame\")`);
expect(sources.get('<async python>').text).toContain(`
expect(sources.get('Python Async').text).toContain(`
# Click text=Hi, I'm frame
await page.frame(name=\"one\").click(\"text=Hi, I'm frame\")`);
expect(sources.get('<csharp>').text).toContain(`
expect(sources.get('C#').text).toContain(`
// Click text=Hi, I'm frame
await page.Frame(\"one\").ClickAsync(\"text=Hi, I'm frame\");`);
[sources] = await Promise.all([
recorder.waitForOutput('<javascript>', 'two'),
recorder.waitForOutput('JavaScript', 'two'),
frameTwo.click('div'),
]);
expect(sources.get('<javascript>').text).toContain(`
expect(sources.get('JavaScript').text).toContain(`
// Click text=Hi, I'm frame
await page.frame({
name: 'two'
}).click('text=Hi, I\\'m frame');`);
expect(sources.get('<java>').text).toContain(`
expect(sources.get('Java').text).toContain(`
// Click text=Hi, I'm frame
page.frame("two").click("text=Hi, I'm frame");`);
expect(sources.get('<python>').text).toContain(`
expect(sources.get('Python').text).toContain(`
# Click text=Hi, I'm frame
page.frame(name=\"two\").click(\"text=Hi, I'm frame\")`);
expect(sources.get('<async python>').text).toContain(`
expect(sources.get('Python Async').text).toContain(`
# Click text=Hi, I'm frame
await page.frame(name=\"two\").click(\"text=Hi, I'm frame\")`);
expect(sources.get('<csharp>').text).toContain(`
expect(sources.get('C#').text).toContain(`
// Click text=Hi, I'm frame
await page.Frame(\"two\").ClickAsync(\"text=Hi, I'm frame\");`);
[sources] = await Promise.all([
recorder.waitForOutput('<javascript>', 'url: \''),
recorder.waitForOutput('JavaScript', 'url: \''),
otherFrame.click('div'),
]);
expect(sources.get('<javascript>').text).toContain(`
expect(sources.get('JavaScript').text).toContain(`
// Click text=Hi, I'm frame
await page.frame({
url: 'http://localhost:${server.PORT}/frames/frame.html'
}).click('text=Hi, I\\'m frame');`);
expect(sources.get('<java>').text).toContain(`
expect(sources.get('Java').text).toContain(`
// Click text=Hi, I'm frame
page.frameByUrl("http://localhost:${server.PORT}/frames/frame.html").click("text=Hi, I'm frame");`);
expect(sources.get('<python>').text).toContain(`
expect(sources.get('Python').text).toContain(`
# Click text=Hi, I'm frame
page.frame(url=\"http://localhost:${server.PORT}/frames/frame.html\").click(\"text=Hi, I'm frame\")`);
expect(sources.get('<async python>').text).toContain(`
expect(sources.get('Python Async').text).toContain(`
# Click text=Hi, I'm frame
await page.frame(url=\"http://localhost:${server.PORT}/frames/frame.html\").click(\"text=Hi, I'm frame\")`);
expect(sources.get('<csharp>').text).toContain(`
expect(sources.get('C#').text).toContain(`
// Click text=Hi, I'm frame
await page.FrameByUrl(\"http://localhost:${server.PORT}/frames/frame.html\").ClickAsync(\"text=Hi, I'm frame\");`);
});
@ -610,7 +610,7 @@ test.describe('cli codegen', () => {
await page.evaluate('pushState()');
await page.goto(server.PREFIX + '/page2.html');
await recorder.waitForOutput('<javascript>', `await page.goto('${server.PREFIX}/page2.html');`);
await recorder.waitForOutput('JavaScript', `await page.goto('${server.PREFIX}/page2.html');`);
});
test('should record slow navigation signal after mouse move', async ({ page, openRecorder, server }) => {
@ -632,9 +632,9 @@ test.describe('cli codegen', () => {
const [, sources] = await Promise.all([
// This will click, finish the click, then mouse move, then navigate.
page.click('button'),
recorder.waitForOutput('<javascript>', 'waitForNavigation'),
recorder.waitForOutput('JavaScript', 'waitForNavigation'),
]);
expect(sources.get('<javascript>').text).toContain(`page.waitForNavigation(/*{ url: '${server.EMPTY_PAGE}' }*/)`);
expect(sources.get('JavaScript').text).toContain(`page.waitForNavigation(/*{ url: '${server.EMPTY_PAGE}' }*/)`);
});
});

View File

@ -25,7 +25,7 @@ const launchOptions = (channel: string) => {
};
test('should print the correct imports and context options', async ({ browserName, channel, runCLI }) => {
const cli = runCLI([emptyHTML]);
const cli = runCLI(['--target=javascript', emptyHTML]);
const expectedResult = `const { ${browserName} } = require('playwright');
(async () => {
@ -38,7 +38,7 @@ test('should print the correct imports and context options', async ({ browserNam
});
test('should print the correct context options for custom settings', async ({ browserName, channel, runCLI }) => {
const cli = runCLI(['--color-scheme=light', emptyHTML]);
const cli = runCLI(['--color-scheme=light', '--target=javascript', emptyHTML]);
const expectedResult = `const { ${browserName} } = require('playwright');
(async () => {
@ -56,7 +56,7 @@ test('should print the correct context options for custom settings', async ({ br
test('should print the correct context options when using a device', async ({ browserName, channel, runCLI }) => {
test.skip(browserName !== 'chromium');
const cli = runCLI(['--device=Pixel 2', emptyHTML]);
const cli = runCLI(['--device=Pixel 2', '--target=javascript', emptyHTML]);
const expectedResult = `const { chromium, devices } = require('playwright');
(async () => {
@ -73,7 +73,7 @@ test('should print the correct context options when using a device', async ({ br
test('should print the correct context options when using a device and additional options', async ({ browserName, channel, runCLI }) => {
test.skip(browserName !== 'webkit');
const cli = runCLI(['--color-scheme=light', '--device=iPhone 11', emptyHTML]);
const cli = runCLI(['--color-scheme=light', '--device=iPhone 11', '--target=javascript', emptyHTML]);
const expectedResult = `const { webkit, devices } = require('playwright');
(async () => {
@ -90,7 +90,7 @@ test('should print the correct context options when using a device and additiona
test('should save the codegen output to a file if specified', async ({ browserName, channel, runCLI }, testInfo) => {
const tmpFile = testInfo.outputPath('script.js');
const cli = runCLI(['--output', tmpFile, emptyHTML]);
const cli = runCLI(['--output', tmpFile, '--target=javascript', emptyHTML]);
await cli.exited;
const content = fs.readFileSync(tmpFile);
expect(content.toString()).toBe(`const { ${browserName} } = require('playwright');
@ -120,7 +120,7 @@ test('should print load/save storageState', async ({ browserName, channel, runCL
const loadFileName = testInfo.outputPath('load.json');
const saveFileName = testInfo.outputPath('save.json');
await fs.promises.writeFile(loadFileName, JSON.stringify({ cookies: [], origins: [] }), 'utf8');
const cli = runCLI([`--load-storage=${loadFileName}`, `--save-storage=${saveFileName}`, emptyHTML]);
const cli = runCLI([`--load-storage=${loadFileName}`, `--save-storage=${saveFileName}`, '--target=javascript', emptyHTML]);
const expectedResult1 = `const { ${browserName} } = require('playwright');
(async () => {

View File

@ -0,0 +1,93 @@
/**
* 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 fs from 'fs';
import path from 'path';
import { test, expect } from './inspectorTest';
const emptyHTML = new URL('file://' + path.join(__dirname, '..', 'assets', 'empty.html')).toString();
test('should print the correct imports and context options', async ({ runCLI }) => {
const cli = runCLI([emptyHTML]);
const expectedResult = `const { test, expect } = require('@playwright/test');
test('test', async ({ page }) => {
});`;
await cli.waitFor(expectedResult);
expect(cli.text()).toContain(expectedResult);
});
test('should print the correct context options for custom settings', async ({ browserName, channel, runCLI }) => {
const cli = runCLI(['--color-scheme=light', emptyHTML]);
const expectedResult = `const { test, expect } = require('@playwright/test');
test.use({
colorScheme: 'light'
});
test('test', async ({ page }) => {`;
await cli.waitFor(expectedResult);
expect(cli.text()).toContain(expectedResult);
});
test('should print the correct context options when using a device', async ({ browserName, channel, runCLI }) => {
test.skip(browserName !== 'chromium');
const cli = runCLI(['--device=Pixel 2', emptyHTML]);
const expectedResult = `const { test, expect, devices } = require('@playwright/test');
test.use({
...devices['Pixel 2'],
});
test('test', async ({ page }) => {`;
await cli.waitFor(expectedResult);
expect(cli.text()).toContain(expectedResult);
});
test('should print the correct context options when using a device and additional options', async ({ browserName, channel, runCLI }) => {
test.skip(browserName !== 'webkit');
const cli = runCLI(['--color-scheme=light', '--device=iPhone 11', emptyHTML]);
const expectedResult = `const { test, expect, devices } = require('@playwright/test');
test.use({
...devices['iPhone 11'],
colorScheme: 'light'
});
test('test', async ({ page }) => {`;
await cli.waitFor(expectedResult);
expect(cli.text()).toContain(expectedResult);
});
test('should print load storageState', async ({ browserName, channel, runCLI }, testInfo) => {
const loadFileName = testInfo.outputPath('load.json');
const saveFileName = testInfo.outputPath('save.json');
await fs.promises.writeFile(loadFileName, JSON.stringify({ cookies: [], origins: [] }), 'utf8');
const cli = runCLI([`--load-storage=${loadFileName}`, emptyHTML]);
const expectedResult = `const { test, expect } = require('@playwright/test');
test.use({
storageState: '${loadFileName}'
});
test('test', async ({ page }) => {`;
await cli.waitFor(expectedResult);
});