mirror of
https://github.com/microsoft/playwright.git
synced 2024-09-11 20:37:54 +03:00
feat(codegen): allow generating tests (#7049)
This commit is contained in:
parent
ab4398e60a
commit
3b1bae8a40
@ -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 {
|
||||
|
@ -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');
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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();
|
||||
|
@ -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 ' : '';
|
||||
|
@ -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(),
|
||||
|
@ -35,7 +35,7 @@
|
||||
background: none;
|
||||
outline: none;
|
||||
color: var(--toolbar-color);
|
||||
margin-left: 16px;
|
||||
min-width: 100px;
|
||||
}
|
||||
|
||||
.recorder .toolbar-button.toggled.microscope {
|
||||
|
@ -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>
|
||||
|
@ -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,
|
||||
|
@ -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}' }*/)`);
|
||||
});
|
||||
});
|
||||
|
@ -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 () => {
|
||||
|
93
tests/inspector/cli-codegen-test.spec.ts
Normal file
93
tests/inspector/cli-codegen-test.spec.ts
Normal 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);
|
||||
});
|
Loading…
Reference in New Issue
Block a user