fix(codegen): update csharp scripts to new syntax (#6685)
Drive-by: fix middle/right button clicks in codegen.
This commit is contained in:
parent
08773e836b
commit
e4946b79e6
|
|
@ -142,6 +142,7 @@ export class Recorder {
|
||||||
removeEventListeners(this._listeners);
|
removeEventListeners(this._listeners);
|
||||||
this._listeners = [
|
this._listeners = [
|
||||||
addEventListener(document, 'click', event => this._onClick(event as MouseEvent), true),
|
addEventListener(document, 'click', event => this._onClick(event as MouseEvent), true),
|
||||||
|
addEventListener(document, 'auxclick', event => this._onClick(event as MouseEvent), true),
|
||||||
addEventListener(document, 'input', event => this._onInput(event), true),
|
addEventListener(document, 'input', event => this._onInput(event), true),
|
||||||
addEventListener(document, 'keydown', event => this._onKeyDown(event as KeyboardEvent), true),
|
addEventListener(document, 'keydown', event => this._onKeyDown(event as KeyboardEvent), true),
|
||||||
addEventListener(document, 'keyup', event => this._onKeyUp(event as KeyboardEvent), true),
|
addEventListener(document, 'keyup', event => this._onKeyUp(event as KeyboardEvent), true),
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ export class CSharpLanguageGenerator implements LanguageGenerator {
|
||||||
|
|
||||||
generateAction(actionInContext: ActionInContext): string {
|
generateAction(actionInContext: ActionInContext): string {
|
||||||
const { action, pageAlias } = actionInContext;
|
const { action, pageAlias } = actionInContext;
|
||||||
const formatter = new CSharpFormatter(0);
|
const formatter = new CSharpFormatter(8);
|
||||||
formatter.newLine();
|
formatter.newLine();
|
||||||
formatter.add('// ' + actionTitle(action));
|
formatter.add('// ' + actionTitle(action));
|
||||||
|
|
||||||
|
|
@ -41,63 +41,62 @@ export class CSharpLanguageGenerator implements LanguageGenerator {
|
||||||
|
|
||||||
const subject = actionInContext.isMainFrame ? pageAlias :
|
const subject = actionInContext.isMainFrame ? pageAlias :
|
||||||
(actionInContext.frameName ?
|
(actionInContext.frameName ?
|
||||||
`${pageAlias}.GetFrame(name: ${quote(actionInContext.frameName)})` :
|
`${pageAlias}.Frame(${quote(actionInContext.frameName)})` :
|
||||||
`${pageAlias}.GetFrame(url: ${quote(actionInContext.frameUrl)})`);
|
`${pageAlias}.FrameByUrl(${quote(actionInContext.frameUrl)})`);
|
||||||
|
|
||||||
const signals = toSignalMap(action);
|
const signals = toSignalMap(action);
|
||||||
|
|
||||||
if (signals.dialog) {
|
if (signals.dialog) {
|
||||||
formatter.add(` void ${pageAlias}_Dialog${signals.dialog.dialogAlias}_EventHandler(object sender, DialogEventArgs e)
|
formatter.add(` void ${pageAlias}_Dialog${signals.dialog.dialogAlias}_EventHandler(object sender, IDialog dialog)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"Dialog message: {e.Dialog.Message}");
|
Console.WriteLine($"Dialog message: {dialog.Message}");
|
||||||
e.Dialog.DismissAsync();
|
dialog.DismissAsync();
|
||||||
${pageAlias}.Dialog -= ${pageAlias}_Dialog${signals.dialog.dialogAlias}_EventHandler;
|
${pageAlias}.Dialog -= ${pageAlias}_Dialog${signals.dialog.dialogAlias}_EventHandler;
|
||||||
}
|
}
|
||||||
${pageAlias}.Dialog += ${pageAlias}_Dialog${signals.dialog.dialogAlias}_EventHandler;`);
|
${pageAlias}.Dialog += ${pageAlias}_Dialog${signals.dialog.dialogAlias}_EventHandler;`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const emitTaskWhenAll = signals.waitForNavigation || signals.popup || signals.download;
|
const lines: string[] = [];
|
||||||
if (emitTaskWhenAll) {
|
const actionCall = this._generateActionCall(action, actionInContext.isMainFrame);
|
||||||
if (signals.popup)
|
if (signals.waitForNavigation) {
|
||||||
formatter.add(`var ${signals.popup.popupAlias}Task = ${pageAlias}.WaitForEventAsync(PageEvent.Popup)`);
|
lines.push(`await Task.WhenAll(`);
|
||||||
else if (signals.download)
|
lines.push(`${pageAlias}.WaitForNavigationAsync(/* new ${actionInContext.isMainFrame ? 'Page' : 'Frame'}WaitForNavigationOptions`);
|
||||||
formatter.add(`var downloadTask = ${pageAlias}.WaitForEventAsync(PageEvent.Download);`);
|
lines.push(`{`);
|
||||||
|
lines.push(` UrlString = ${quote(signals.waitForNavigation.url)}`);
|
||||||
formatter.add(`await Task.WhenAll(`);
|
lines.push(`} */),`);
|
||||||
|
lines.push(`${subject}.${actionCall});`);
|
||||||
|
} else {
|
||||||
|
lines.push(`await ${subject}.${actionCall};`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Popup signals.
|
if (signals.download) {
|
||||||
if (signals.popup)
|
lines.unshift(`var download${signals.download.downloadAlias} = await ${pageAlias}.RunAndWaitForEventAsync(PageEvent.Download, async () =>\n{`);
|
||||||
formatter.add(`${signals.popup.popupAlias}Task,`);
|
lines.push(`});`);
|
||||||
|
}
|
||||||
|
|
||||||
// Navigation signal.
|
if (signals.popup) {
|
||||||
if (signals.waitForNavigation)
|
lines.unshift(`var ${signals.popup.popupAlias} = await ${pageAlias}.RunAndWaitForEventAsync(PageEvent.Popup, async () =>\n{`);
|
||||||
formatter.add(`${pageAlias}.WaitForNavigationAsync(/*${quote(signals.waitForNavigation.url)}*/),`);
|
lines.push(`});`);
|
||||||
|
}
|
||||||
|
|
||||||
// Download signals.
|
for (const line of lines)
|
||||||
if (signals.download)
|
formatter.add(line);
|
||||||
formatter.add(`downloadTask,`);
|
|
||||||
|
|
||||||
const prefix = (signals.popup || signals.waitForNavigation || signals.download) ? '' : 'await ';
|
|
||||||
const actionCall = this._generateActionCall(action);
|
|
||||||
const suffix = emitTaskWhenAll ? ');' : ';';
|
|
||||||
formatter.add(`${prefix}${subject}.${actionCall}${suffix}`);
|
|
||||||
|
|
||||||
if (signals.assertNavigation)
|
if (signals.assertNavigation)
|
||||||
formatter.add(` // Assert.Equal(${quote(signals.assertNavigation.url)}, ${pageAlias}.Url);`);
|
formatter.add(` // Assert.Equal(${quote(signals.assertNavigation.url)}, ${pageAlias}.Url);`);
|
||||||
return formatter.format();
|
return formatter.format();
|
||||||
}
|
}
|
||||||
|
|
||||||
private _generateActionCall(action: Action): string {
|
private _generateActionCall(action: Action, isPage: boolean): string {
|
||||||
switch (action.name) {
|
switch (action.name) {
|
||||||
case 'openPage':
|
case 'openPage':
|
||||||
throw Error('Not reached');
|
throw Error('Not reached');
|
||||||
case 'closePage':
|
case 'closePage':
|
||||||
return 'CloseAsync()';
|
return 'CloseAsync()';
|
||||||
case 'click': {
|
case 'click': {
|
||||||
let method = 'ClickAsync';
|
let method = 'Click';
|
||||||
if (action.clickCount === 2)
|
if (action.clickCount === 2)
|
||||||
method = 'DblClickAsync';
|
method = 'DblClick';
|
||||||
const modifiers = toModifiers(action.modifiers);
|
const modifiers = toModifiers(action.modifiers);
|
||||||
const options: MouseClickOptions = {};
|
const options: MouseClickOptions = {};
|
||||||
if (action.button !== 'left')
|
if (action.button !== 'left')
|
||||||
|
|
@ -106,8 +105,10 @@ export class CSharpLanguageGenerator implements LanguageGenerator {
|
||||||
options.modifiers = modifiers;
|
options.modifiers = modifiers;
|
||||||
if (action.clickCount > 2)
|
if (action.clickCount > 2)
|
||||||
options.clickCount = action.clickCount;
|
options.clickCount = action.clickCount;
|
||||||
const optionsString = formatOptions(options, true, false);
|
if (!Object.entries(options).length)
|
||||||
return `${method}(${quote(action.selector)}${optionsString})`;
|
return `${method}Async(${quote(action.selector)})`;
|
||||||
|
const optionsString = formatObject(options, ' ', (isPage ? 'Page' : 'Frame') + method + 'Options');
|
||||||
|
return `${method}Async(${quote(action.selector)}, ${optionsString})`;
|
||||||
}
|
}
|
||||||
case 'check':
|
case 'check':
|
||||||
return `CheckAsync(${quote(action.selector)})`;
|
return `CheckAsync(${quote(action.selector)})`;
|
||||||
|
|
@ -116,7 +117,7 @@ export class CSharpLanguageGenerator implements LanguageGenerator {
|
||||||
case 'fill':
|
case 'fill':
|
||||||
return `FillAsync(${quote(action.selector)}, ${quote(action.text)})`;
|
return `FillAsync(${quote(action.selector)}, ${quote(action.text)})`;
|
||||||
case 'setInputFiles':
|
case 'setInputFiles':
|
||||||
return `SetInputFilesAsync(${quote(action.selector)}, ${formatObject(action.files.length === 1 ? action.files[0] : action.files)})`;
|
return `SetInputFilesAsync(${quote(action.selector)}, ${formatObject(action.files)})`;
|
||||||
case 'press': {
|
case 'press': {
|
||||||
const modifiers = toModifiers(action.modifiers);
|
const modifiers = toModifiers(action.modifiers);
|
||||||
const shortcut = [...modifiers, action.key].join('+');
|
const shortcut = [...modifiers, action.key].join('+');
|
||||||
|
|
@ -125,68 +126,37 @@ export class CSharpLanguageGenerator implements LanguageGenerator {
|
||||||
case 'navigate':
|
case 'navigate':
|
||||||
return `GotoAsync(${quote(action.url)})`;
|
return `GotoAsync(${quote(action.url)})`;
|
||||||
case 'select':
|
case 'select':
|
||||||
return `SelectOptionAsync(${quote(action.selector)}, ${formatObject(action.options.length > 1 ? action.options : action.options[0])})`;
|
return `SelectOptionAsync(${quote(action.selector)}, ${formatObject(action.options)})`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
generateHeader(options: LanguageGeneratorOptions): string {
|
generateHeader(options: LanguageGeneratorOptions): string {
|
||||||
const formatter = new CSharpFormatter(0);
|
const formatter = new CSharpFormatter(0);
|
||||||
formatter.add(`
|
formatter.add(`
|
||||||
await Playwright.InstallAsync();
|
using System;
|
||||||
using var playwright = await Playwright.CreateAsync();
|
using System.Threading.Tasks;
|
||||||
await using var browser = await playwright.${toPascal(options.browserName)}.LaunchAsync(${formatArgs(options.launchOptions)}
|
using Microsoft.Playwright;
|
||||||
);
|
|
||||||
var context = await browser.NewContextAsync(${formatContextOptions(options.contextOptions, options.deviceName)});`);
|
class Example
|
||||||
|
{
|
||||||
|
static async Task Main(string[] args)
|
||||||
|
{
|
||||||
|
using var playwright = await Playwright.CreateAsync();
|
||||||
|
await using var browser = await playwright.${toPascal(options.browserName)}.LaunchAsync(${formatObject(options.launchOptions, ' ', 'BrowserTypeLaunchOptions')});
|
||||||
|
var context = await browser.NewContextAsync(${formatContextOptions(options.contextOptions, options.deviceName)});`);
|
||||||
return formatter.format();
|
return formatter.format();
|
||||||
}
|
}
|
||||||
|
|
||||||
generateFooter(saveStorage: string | undefined): string {
|
generateFooter(saveStorage: string | undefined): string {
|
||||||
const storageStateLine = saveStorage ? `\nawait context.StorageStateAsync(path: "${saveStorage}");` : '';
|
const storageStateLine = saveStorage ? `\n await context.StorageStateAsync(new BrowserContextStorageStateOptions\n {\n Path = ${quote(saveStorage)}\n });\n` : '';
|
||||||
return `\n// ---------------------${storageStateLine}`;
|
return `${storageStateLine} }
|
||||||
|
}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatValue(value: any): string {
|
|
||||||
if (value === false)
|
|
||||||
return 'false';
|
|
||||||
if (value === true)
|
|
||||||
return 'true';
|
|
||||||
if (value === undefined)
|
|
||||||
return 'null';
|
|
||||||
if (Array.isArray(value))
|
|
||||||
return `new [] {${value.map(formatValue).join(', ')}}`;
|
|
||||||
if (typeof value === 'string')
|
|
||||||
return quote(value);
|
|
||||||
return String(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatOptions(value: any, hasArguments: boolean, isInitializing: boolean): string {
|
|
||||||
const keys = Object.keys(value);
|
|
||||||
if (!keys.length)
|
|
||||||
return '';
|
|
||||||
return (hasArguments ? ', ' : '') + keys.map(key => `${key}${isInitializing ? ': ' : ' = '}${formatValue(value[key])}`).join(', ');
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatArgs(value: any, indent = ' '): string {
|
|
||||||
if (typeof value === 'string')
|
|
||||||
return quote(value);
|
|
||||||
if (Array.isArray(value))
|
|
||||||
return `new [] {${value.map(o => formatObject(o)).join(', ')}}`;
|
|
||||||
if (typeof value === 'object') {
|
|
||||||
const keys = Object.keys(value);
|
|
||||||
if (!keys.length)
|
|
||||||
return '';
|
|
||||||
const tokens: string[] = [];
|
|
||||||
for (const key of keys)
|
|
||||||
tokens.push(`${keys.length !== 1 ? indent : ''}${key}: ${formatObject(value[key], indent, key)}`);
|
|
||||||
return `\n${indent}${tokens.join(`,\n${indent}`)}`;
|
|
||||||
}
|
|
||||||
return String(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatObject(value: any, indent = ' ', name = ''): string {
|
function formatObject(value: any, indent = ' ', name = ''): string {
|
||||||
if (typeof value === 'string') {
|
if (typeof value === 'string') {
|
||||||
if (name === 'permissions' || name === 'colorScheme')
|
if (['permissions', 'colorScheme', 'modifiers', 'button'].includes(name))
|
||||||
return `${getClassName(name)}.${toPascal(value)}`;
|
return `${getClassName(name)}.${toPascal(value)}`;
|
||||||
return quote(value);
|
return quote(value);
|
||||||
}
|
}
|
||||||
|
|
@ -195,10 +165,12 @@ function formatObject(value: any, indent = ' ', name = ''): string {
|
||||||
if (typeof value === 'object') {
|
if (typeof value === 'object') {
|
||||||
const keys = Object.keys(value);
|
const keys = Object.keys(value);
|
||||||
if (!keys.length)
|
if (!keys.length)
|
||||||
return '';
|
return name ? `new ${getClassName(name)}` : '';
|
||||||
const tokens: string[] = [];
|
const tokens: string[] = [];
|
||||||
for (const key of keys)
|
for (const key of keys) {
|
||||||
tokens.push(`${toPascal(key)} = ${formatObject(value[key], indent, key)},`);
|
const property = getPropertyName(key);
|
||||||
|
tokens.push(`${property} = ${formatObject(value[key], indent, key)},`);
|
||||||
|
}
|
||||||
if (name)
|
if (name)
|
||||||
return `new ${getClassName(name)}\n{\n${indent}${tokens.join(`\n${indent}`)}\n${indent}}`;
|
return `new ${getClassName(name)}\n{\n${indent}${tokens.join(`\n${indent}`)}\n${indent}}`;
|
||||||
return `{\n${indent}${tokens.join(`\n${indent}`)}\n${indent}}`;
|
return `{\n${indent}${tokens.join(`\n${indent}`)}\n${indent}}`;
|
||||||
|
|
@ -214,31 +186,37 @@ function getClassName(value: string): string {
|
||||||
case 'viewport': return 'ViewportSize';
|
case 'viewport': return 'ViewportSize';
|
||||||
case 'proxy': return 'ProxySettings';
|
case 'proxy': return 'ProxySettings';
|
||||||
case 'permissions': return 'ContextPermission';
|
case 'permissions': return 'ContextPermission';
|
||||||
|
case 'modifiers': return 'KeyboardModifier';
|
||||||
|
case 'button': return 'MouseButton';
|
||||||
default: return toPascal(value);
|
default: return toPascal(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getPropertyName(key: string): string {
|
||||||
|
switch (key) {
|
||||||
|
case 'storageState': return 'StorageStatePath';
|
||||||
|
case 'viewport': return 'ViewportSize';
|
||||||
|
default: return toPascal(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function toPascal(value: string): string {
|
function toPascal(value: string): string {
|
||||||
return value[0].toUpperCase() + value.slice(1);
|
return value[0].toUpperCase() + value.slice(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatContextOptions(options: BrowserContextOptions, deviceName: string | undefined): string {
|
function formatContextOptions(options: BrowserContextOptions, deviceName: string | undefined): string {
|
||||||
const device = deviceName && deviceDescriptors[deviceName];
|
const device = deviceName && deviceDescriptors[deviceName];
|
||||||
if (!device)
|
if (!device) {
|
||||||
return formatArgs(options);
|
if (!Object.entries(options).length)
|
||||||
const serializedObject = formatObject(sanitizeDeviceOptions(device, options), ' ');
|
return '';
|
||||||
// When there are no additional context options, we still want to spread the device inside.
|
return formatObject(options, ' ', 'BrowserNewContextOptions');
|
||||||
|
|
||||||
if (!serializedObject)
|
|
||||||
return `playwright.Devices["${deviceName}"]`;
|
|
||||||
let result = `new BrowserContextOptions(playwright.Devices["${deviceName}"])`;
|
|
||||||
|
|
||||||
if (serializedObject) {
|
|
||||||
const lines = serializedObject.split('\n');
|
|
||||||
result = `${result} \n${lines.join('\n')}`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
options = sanitizeDeviceOptions(device, options);
|
||||||
|
if (!Object.entries(options).length)
|
||||||
|
return `playwright.Devices[${quote(deviceName!)}]`;
|
||||||
|
|
||||||
|
return formatObject(options, ' ', `BrowserNewContextOptions(playwright.Devices[${quote(deviceName!)}])`);
|
||||||
}
|
}
|
||||||
|
|
||||||
class CSharpFormatter {
|
class CSharpFormatter {
|
||||||
|
|
@ -278,7 +256,7 @@ class CSharpFormatter {
|
||||||
line = spaces + extraSpaces + line;
|
line = spaces + extraSpaces + line;
|
||||||
if (line.endsWith('{') || line.endsWith('[') || line.endsWith('('))
|
if (line.endsWith('{') || line.endsWith('[') || line.endsWith('('))
|
||||||
spaces += this._baseIndent;
|
spaces += this._baseIndent;
|
||||||
if (line.endsWith('});'))
|
if (line.endsWith('));'))
|
||||||
spaces = spaces.substring(this._baseIndent.length);
|
spaces = spaces.substring(this._baseIndent.length);
|
||||||
|
|
||||||
return this._baseOffset + line;
|
return this._baseOffset + line;
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,7 @@ export type PopupSignal = BaseSignal & {
|
||||||
|
|
||||||
export type DownloadSignal = BaseSignal & {
|
export type DownloadSignal = BaseSignal & {
|
||||||
name: 'download',
|
name: 'download',
|
||||||
|
downloadAlias: string,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type DialogSignal = BaseSignal & {
|
export type DialogSignal = BaseSignal & {
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ export class RecorderSupplement implements InstrumentationListener {
|
||||||
private _pageAliases = new Map<Page, string>();
|
private _pageAliases = new Map<Page, string>();
|
||||||
private _lastPopupOrdinal = 0;
|
private _lastPopupOrdinal = 0;
|
||||||
private _lastDialogOrdinal = 0;
|
private _lastDialogOrdinal = 0;
|
||||||
|
private _lastDownloadOrdinal = 0;
|
||||||
private _timers = new Set<NodeJS.Timeout>();
|
private _timers = new Set<NodeJS.Timeout>();
|
||||||
private _context: BrowserContext;
|
private _context: BrowserContext;
|
||||||
private _mode: Mode;
|
private _mode: Mode;
|
||||||
|
|
@ -381,7 +382,7 @@ export class RecorderSupplement implements InstrumentationListener {
|
||||||
}
|
}
|
||||||
private _onDownload(page: Page) {
|
private _onDownload(page: Page) {
|
||||||
const pageAlias = this._pageAliases.get(page)!;
|
const pageAlias = this._pageAliases.get(page)!;
|
||||||
this._generator.signal(pageAlias, page.mainFrame(), { name: 'download' });
|
this._generator.signal(pageAlias, page.mainFrame(), { name: 'download', downloadAlias: String(++this._lastDownloadOrdinal) });
|
||||||
}
|
}
|
||||||
|
|
||||||
private _onDialog(page: Page) {
|
private _onDialog(page: Page) {
|
||||||
|
|
|
||||||
|
|
@ -51,8 +51,8 @@ test.describe('cli codegen', () => {
|
||||||
page.click("text=Submit");`);
|
page.click("text=Submit");`);
|
||||||
|
|
||||||
expect(sources.get('<csharp>').text).toContain(`
|
expect(sources.get('<csharp>').text).toContain(`
|
||||||
// Click text=Submit
|
// Click text=Submit
|
||||||
await page.ClickAsync("text=Submit");`);
|
await page.ClickAsync("text=Submit");`);
|
||||||
|
|
||||||
expect(message.text()).toBe('click');
|
expect(message.text()).toBe('click');
|
||||||
});
|
});
|
||||||
|
|
@ -125,8 +125,8 @@ await page.ClickAsync("text=Submit");`);
|
||||||
page.click("text=Submit");`);
|
page.click("text=Submit");`);
|
||||||
|
|
||||||
expect(sources.get('<csharp>').text).toContain(`
|
expect(sources.get('<csharp>').text).toContain(`
|
||||||
// Click text=Submit
|
// Click text=Submit
|
||||||
await page.ClickAsync("text=Submit");`);
|
await page.ClickAsync("text=Submit");`);
|
||||||
|
|
||||||
expect(message.text()).toBe('click');
|
expect(message.text()).toBe('click');
|
||||||
});
|
});
|
||||||
|
|
@ -194,8 +194,8 @@ await page.ClickAsync("text=Submit");`);
|
||||||
await page.fill(\"input[name=\\\"name\\\"]\", \"John\")`);
|
await page.fill(\"input[name=\\\"name\\\"]\", \"John\")`);
|
||||||
|
|
||||||
expect(sources.get('<csharp>').text).toContain(`
|
expect(sources.get('<csharp>').text).toContain(`
|
||||||
// Fill input[name="name"]
|
// Fill input[name="name"]
|
||||||
await page.FillAsync(\"input[name=\\\"name\\\"]\", \"John\");`);
|
await page.FillAsync(\"input[name=\\\"name\\\"]\", \"John\");`);
|
||||||
|
|
||||||
expect(message.text()).toBe('John');
|
expect(message.text()).toBe('John');
|
||||||
});
|
});
|
||||||
|
|
@ -251,8 +251,8 @@ await page.FillAsync(\"input[name=\\\"name\\\"]\", \"John\");`);
|
||||||
await page.press(\"input[name=\\\"name\\\"]\", \"Shift+Enter\")`);
|
await page.press(\"input[name=\\\"name\\\"]\", \"Shift+Enter\")`);
|
||||||
|
|
||||||
expect(sources.get('<csharp>').text).toContain(`
|
expect(sources.get('<csharp>').text).toContain(`
|
||||||
// Press Enter with modifiers
|
// Press Enter with modifiers
|
||||||
await page.PressAsync(\"input[name=\\\"name\\\"]\", \"Shift+Enter\");`);
|
await page.PressAsync(\"input[name=\\\"name\\\"]\", \"Shift+Enter\");`);
|
||||||
|
|
||||||
expect(messages[0].text()).toBe('press');
|
expect(messages[0].text()).toBe('press');
|
||||||
});
|
});
|
||||||
|
|
@ -369,8 +369,8 @@ await page.PressAsync(\"input[name=\\\"name\\\"]\", \"Shift+Enter\");`);
|
||||||
await page.check(\"input[name=\\\"accept\\\"]\")`);
|
await page.check(\"input[name=\\\"accept\\\"]\")`);
|
||||||
|
|
||||||
expect(sources.get('<csharp>').text).toContain(`
|
expect(sources.get('<csharp>').text).toContain(`
|
||||||
// Check input[name="accept"]
|
// Check input[name="accept"]
|
||||||
await page.CheckAsync(\"input[name=\\\"accept\\\"]\");`);
|
await page.CheckAsync(\"input[name=\\\"accept\\\"]\");`);
|
||||||
|
|
||||||
expect(message.text()).toBe('true');
|
expect(message.text()).toBe('true');
|
||||||
});
|
});
|
||||||
|
|
@ -426,8 +426,8 @@ await page.CheckAsync(\"input[name=\\\"accept\\\"]\");`);
|
||||||
await page.uncheck(\"input[name=\\\"accept\\\"]\")`);
|
await page.uncheck(\"input[name=\\\"accept\\\"]\")`);
|
||||||
|
|
||||||
expect(sources.get('<csharp>').text).toContain(`
|
expect(sources.get('<csharp>').text).toContain(`
|
||||||
// Uncheck input[name="accept"]
|
// Uncheck input[name="accept"]
|
||||||
await page.UncheckAsync(\"input[name=\\\"accept\\\"]\");`);
|
await page.UncheckAsync(\"input[name=\\\"accept\\\"]\");`);
|
||||||
|
|
||||||
expect(message.text()).toBe('false');
|
expect(message.text()).toBe('false');
|
||||||
});
|
});
|
||||||
|
|
@ -463,8 +463,8 @@ await page.UncheckAsync(\"input[name=\\\"accept\\\"]\");`);
|
||||||
await page.select_option(\"select\", \"2\")`);
|
await page.select_option(\"select\", \"2\")`);
|
||||||
|
|
||||||
expect(sources.get('<csharp>').text).toContain(`
|
expect(sources.get('<csharp>').text).toContain(`
|
||||||
// Select 2
|
// Select 2
|
||||||
await page.SelectOptionAsync(\"select\", \"2\");`);
|
await page.SelectOptionAsync(\"select\", new[] { \"2\" });`);
|
||||||
|
|
||||||
expect(message.text()).toBe('2');
|
expect(message.text()).toBe('2');
|
||||||
});
|
});
|
||||||
|
|
@ -510,10 +510,10 @@ await page.SelectOptionAsync(\"select\", \"2\");`);
|
||||||
page1 = await popup_info.value`);
|
page1 = await popup_info.value`);
|
||||||
|
|
||||||
expect(sources.get('<csharp>').text).toContain(`
|
expect(sources.get('<csharp>').text).toContain(`
|
||||||
var page1Task = page.WaitForEventAsync(PageEvent.Popup)
|
var page1 = await page.RunAndWaitForEventAsync(PageEvent.Popup, async () =>
|
||||||
await Task.WhenAll(
|
{
|
||||||
page1Task,
|
await page.ClickAsync(\"text=link\");
|
||||||
page.ClickAsync(\"text=link\"));`);
|
});`);
|
||||||
|
|
||||||
expect(popup.url()).toBe('about:blank');
|
expect(popup.url()).toBe('about:blank');
|
||||||
});
|
});
|
||||||
|
|
@ -552,9 +552,9 @@ await Task.WhenAll(
|
||||||
# assert page.url == \"about:blank#foo\"`);
|
# assert page.url == \"about:blank#foo\"`);
|
||||||
|
|
||||||
expect(sources.get('<csharp>').text).toContain(`
|
expect(sources.get('<csharp>').text).toContain(`
|
||||||
// Click text=link
|
// Click text=link
|
||||||
await page.ClickAsync(\"text=link\");
|
await page.ClickAsync(\"text=link\");
|
||||||
// Assert.Equal(\"about:blank#foo\", page.Url);`);
|
// Assert.Equal(\"about:blank#foo\", page.Url);`);
|
||||||
|
|
||||||
expect(page.url()).toContain('about:blank#foo');
|
expect(page.url()).toContain('about:blank#foo');
|
||||||
});
|
});
|
||||||
|
|
@ -601,10 +601,13 @@ await page.ClickAsync(\"text=link\");
|
||||||
await page.click(\"text=link\")`);
|
await page.click(\"text=link\")`);
|
||||||
|
|
||||||
expect(sources.get('<csharp>').text).toContain(`
|
expect(sources.get('<csharp>').text).toContain(`
|
||||||
// Click text=link
|
// Click text=link
|
||||||
await Task.WhenAll(
|
await Task.WhenAll(
|
||||||
page.WaitForNavigationAsync(/*\"about:blank#foo\"*/),
|
page.WaitForNavigationAsync(/* new PageWaitForNavigationOptions
|
||||||
page.ClickAsync(\"text=link\"));`);
|
{
|
||||||
|
UrlString = \"about:blank#foo\"
|
||||||
|
} */),
|
||||||
|
page.ClickAsync(\"text=link\"));`);
|
||||||
|
|
||||||
expect(page.url()).toContain('about:blank#foo');
|
expect(page.url()).toContain('about:blank#foo');
|
||||||
});
|
});
|
||||||
|
|
@ -622,4 +625,36 @@ await Task.WhenAll(
|
||||||
expect(recorder.sources().get('<javascript>').text).not.toContain(`await page.press('input', 'AltGraph');`);
|
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');`);
|
expect(recorder.sources().get('<javascript>').text).toContain(`await page.fill('input', 'playwright@example.com');`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should middle click', async ({ page, openRecorder, server }) => {
|
||||||
|
const recorder = await openRecorder();
|
||||||
|
|
||||||
|
await recorder.setContentAndWait(`<a href${JSON.stringify(server.EMPTY_PAGE)}>Click me</a>`);
|
||||||
|
|
||||||
|
const [sources] = await Promise.all([
|
||||||
|
recorder.waitForOutput('<javascript>', 'click'),
|
||||||
|
page.click('a', { button: 'middle' }),
|
||||||
|
]);
|
||||||
|
|
||||||
|
expect(sources.get('<javascript>').text).toContain(`
|
||||||
|
await page.click('text=Click me', {
|
||||||
|
button: 'middle'
|
||||||
|
});`);
|
||||||
|
|
||||||
|
expect(sources.get('<python>').text).toContain(`
|
||||||
|
page.click("text=Click me", button="middle")`);
|
||||||
|
|
||||||
|
expect(sources.get('<async python>').text).toContain(`
|
||||||
|
await page.click("text=Click me", button="middle")`);
|
||||||
|
|
||||||
|
// TODO: fix this for java
|
||||||
|
// expect(sources.get('<java>').text).toContain(`
|
||||||
|
// page.click("text=Click me", foo);`);
|
||||||
|
|
||||||
|
expect(sources.get('<csharp>').text).toContain(`
|
||||||
|
await page.ClickAsync("text=Click me", new PageClickOptions
|
||||||
|
{
|
||||||
|
Button = MouseButton.Middle,
|
||||||
|
});`);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -43,8 +43,8 @@ test.describe('cli codegen', () => {
|
||||||
page = await context.new_page()`);
|
page = await context.new_page()`);
|
||||||
|
|
||||||
expect(sources.get('<csharp>').text).toContain(`
|
expect(sources.get('<csharp>').text).toContain(`
|
||||||
// Open new page
|
// Open new page
|
||||||
var page = await context.NewPageAsync();`);
|
var page = await context.NewPageAsync();`);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should contain second page', async ({ openRecorder, page }) => {
|
test('should contain second page', async ({ openRecorder, page }) => {
|
||||||
|
|
@ -71,8 +71,8 @@ var page = await context.NewPageAsync();`);
|
||||||
page1 = await context.new_page()`);
|
page1 = await context.new_page()`);
|
||||||
|
|
||||||
expect(sources.get('<csharp>').text).toContain(`
|
expect(sources.get('<csharp>').text).toContain(`
|
||||||
// Open new page
|
// Open new page
|
||||||
var page1 = await context.NewPageAsync();`);
|
var page1 = await context.NewPageAsync();`);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should contain close page', async ({ openRecorder, page }) => {
|
test('should contain close page', async ({ openRecorder, page }) => {
|
||||||
|
|
@ -96,7 +96,7 @@ var page1 = await context.NewPageAsync();`);
|
||||||
await page.close()`);
|
await page.close()`);
|
||||||
|
|
||||||
expect(sources.get('<csharp>').text).toContain(`
|
expect(sources.get('<csharp>').text).toContain(`
|
||||||
await page.CloseAsync();`);
|
await page.CloseAsync();`);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should not lead to an error if html gets clicked', async ({ page, openRecorder }) => {
|
test('should not lead to an error if html gets clicked', async ({ page, openRecorder }) => {
|
||||||
|
|
@ -147,9 +147,8 @@ await page.CloseAsync();`);
|
||||||
await page.set_input_files(\"input[type=\\\"file\\\"]\", \"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('<csharp>').text).toContain(`
|
||||||
// Upload file-to-upload.txt
|
// Upload file-to-upload.txt
|
||||||
await page.SetInputFilesAsync(\"input[type=\\\"file\\\"]\", \"file-to-upload.txt\");`);
|
await page.SetInputFilesAsync(\"input[type=\\\"file\\\"]\", new[] { \"file-to-upload.txt\" });`);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should upload multiple files', async ({ page, openRecorder, browserName, asset }) => {
|
test('should upload multiple files', async ({ page, openRecorder, browserName, asset }) => {
|
||||||
|
|
@ -185,8 +184,8 @@ await page.SetInputFilesAsync(\"input[type=\\\"file\\\"]\", \"file-to-upload.txt
|
||||||
await page.set_input_files(\"input[type=\\\"file\\\"]\", [\"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('<csharp>').text).toContain(`
|
||||||
// Upload file-to-upload.txt, file-to-upload-2.txt
|
// 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\" });`);
|
await page.SetInputFilesAsync(\"input[type=\\\"file\\\"]\", new[] { \"file-to-upload.txt\", \"file-to-upload-2.txt\" });`);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should clear files', async ({ page, openRecorder, browserName, asset }) => {
|
test('should clear files', async ({ page, openRecorder, browserName, asset }) => {
|
||||||
|
|
@ -222,8 +221,8 @@ await page.SetInputFilesAsync(\"input[type=\\\"file\\\"]\", new[] { \"file-to-up
|
||||||
await page.set_input_files(\"input[type=\\\"file\\\"]\", []`);
|
await page.set_input_files(\"input[type=\\\"file\\\"]\", []`);
|
||||||
|
|
||||||
expect(sources.get('<csharp>').text).toContain(`
|
expect(sources.get('<csharp>').text).toContain(`
|
||||||
// Clear selected files
|
// Clear selected files
|
||||||
await page.SetInputFilesAsync(\"input[type=\\\"file\\\"]\", new[] { });`);
|
await page.SetInputFilesAsync(\"input[type=\\\"file\\\"]\", new[] { });`);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -277,11 +276,11 @@ await page.SetInputFilesAsync(\"input[type=\\\"file\\\"]\", new[] { });`);
|
||||||
download = await download_info.value`);
|
download = await download_info.value`);
|
||||||
|
|
||||||
expect(sources.get('<csharp>').text).toContain(`
|
expect(sources.get('<csharp>').text).toContain(`
|
||||||
// Click text=Download
|
// Click text=Download
|
||||||
var downloadTask = page.WaitForEventAsync(PageEvent.Download);
|
var download1 = await page.RunAndWaitForEventAsync(PageEvent.Download, async () =>
|
||||||
await Task.WhenAll(
|
{
|
||||||
downloadTask,
|
await page.ClickAsync(\"text=Download\");
|
||||||
page.ClickAsync(\"text=Download\"));`);
|
});`);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should handle dialogs', async ({ page, openRecorder }) => {
|
test('should handle dialogs', async ({ page, openRecorder }) => {
|
||||||
|
|
@ -325,15 +324,15 @@ await Task.WhenAll(
|
||||||
await page.click(\"text=click me\")`);
|
await page.click(\"text=click me\")`);
|
||||||
|
|
||||||
expect(sources.get('<csharp>').text).toContain(`
|
expect(sources.get('<csharp>').text).toContain(`
|
||||||
// Click text=click me
|
// Click text=click me
|
||||||
void page_Dialog1_EventHandler(object sender, DialogEventArgs e)
|
void page_Dialog1_EventHandler(object sender, IDialog dialog)
|
||||||
{
|
{
|
||||||
Console.WriteLine($\"Dialog message: {e.Dialog.Message}\");
|
Console.WriteLine($\"Dialog message: {dialog.Message}\");
|
||||||
e.Dialog.DismissAsync();
|
dialog.DismissAsync();
|
||||||
page.Dialog -= page_Dialog1_EventHandler;
|
page.Dialog -= page_Dialog1_EventHandler;
|
||||||
}
|
}
|
||||||
page.Dialog += page_Dialog1_EventHandler;
|
page.Dialog += page_Dialog1_EventHandler;
|
||||||
await page.ClickAsync(\"text=click me\");`);
|
await page.ClickAsync(\"text=click me\");`);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -375,9 +374,9 @@ await page.ClickAsync(\"text=click me\");`);
|
||||||
page1 = await context.new_page()
|
page1 = await context.new_page()
|
||||||
await page1.goto("about:blank?foo")`);
|
await page1.goto("about:blank?foo")`);
|
||||||
expect(sources.get('<csharp>').text).toContain(`
|
expect(sources.get('<csharp>').text).toContain(`
|
||||||
// Open new page
|
// Open new page
|
||||||
var page1 = await context.NewPageAsync();
|
var page1 = await context.NewPageAsync();
|
||||||
await page1.GotoAsync("about:blank?foo");`);
|
await page1.GotoAsync("about:blank?foo");`);
|
||||||
} else if (browserName === 'firefox') {
|
} else if (browserName === 'firefox') {
|
||||||
expect(sources.get('<javascript>').text).toContain(`
|
expect(sources.get('<javascript>').text).toContain(`
|
||||||
// Click text=link
|
// Click text=link
|
||||||
|
|
@ -521,8 +520,8 @@ await page1.GotoAsync("about:blank?foo");`);
|
||||||
await page.frame(name=\"one\").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('<csharp>').text).toContain(`
|
||||||
// Click text=Hi, I'm frame
|
// Click text=Hi, I'm frame
|
||||||
await page.GetFrame(name: \"one\").ClickAsync(\"text=Hi, I'm frame\");`);
|
await page.Frame(\"one\").ClickAsync(\"text=Hi, I'm frame\");`);
|
||||||
|
|
||||||
[sources] = await Promise.all([
|
[sources] = await Promise.all([
|
||||||
recorder.waitForOutput('<javascript>', 'two'),
|
recorder.waitForOutput('<javascript>', 'two'),
|
||||||
|
|
@ -548,8 +547,8 @@ await page.GetFrame(name: \"one\").ClickAsync(\"text=Hi, I'm frame\");`);
|
||||||
await page.frame(name=\"two\").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('<csharp>').text).toContain(`
|
||||||
// Click text=Hi, I'm frame
|
// Click text=Hi, I'm frame
|
||||||
await page.GetFrame(name: \"two\").ClickAsync(\"text=Hi, I'm frame\");`);
|
await page.Frame(\"two\").ClickAsync(\"text=Hi, I'm frame\");`);
|
||||||
|
|
||||||
[sources] = await Promise.all([
|
[sources] = await Promise.all([
|
||||||
recorder.waitForOutput('<javascript>', 'url: \''),
|
recorder.waitForOutput('<javascript>', 'url: \''),
|
||||||
|
|
@ -575,8 +574,8 @@ await page.GetFrame(name: \"two\").ClickAsync(\"text=Hi, I'm frame\");`);
|
||||||
await page.frame(url=\"http://localhost:${server.PORT}/frames/frame.html\").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('<csharp>').text).toContain(`
|
||||||
// Click text=Hi, I'm frame
|
// Click text=Hi, I'm frame
|
||||||
await page.GetFrame(url: \"http://localhost:${server.PORT}/frames/frame.html\").ClickAsync(\"text=Hi, I'm frame\");`);
|
await page.FrameByUrl(\"http://localhost:${server.PORT}/frames/frame.html\").ClickAsync(\"text=Hi, I'm frame\");`);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should record navigations after identical pushState', async ({ page, openRecorder, server }) => {
|
test('should record navigations after identical pushState', async ({ page, openRecorder, server }) => {
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ import { test, expect } from './inspectorTest';
|
||||||
|
|
||||||
const emptyHTML = new URL('file://' + path.join(__dirname, '..', 'assets', 'empty.html')).toString();
|
const emptyHTML = new URL('file://' + path.join(__dirname, '..', 'assets', 'empty.html')).toString();
|
||||||
const launchOptions = (channel: string) => {
|
const launchOptions = (channel: string) => {
|
||||||
return channel ? `headless: false,\n channel: "${channel}"` : 'headless: false';
|
return channel ? `Headless = false,\n Channel = "${channel}",` : `Headless = false,`;
|
||||||
};
|
};
|
||||||
|
|
||||||
function capitalize(browserName: string): string {
|
function capitalize(browserName: string): string {
|
||||||
|
|
@ -29,12 +29,12 @@ function capitalize(browserName: string): string {
|
||||||
|
|
||||||
test('should print the correct imports and context options', async ({ browserName, channel, runCLI }) => {
|
test('should print the correct imports and context options', async ({ browserName, channel, runCLI }) => {
|
||||||
const cli = runCLI(['--target=csharp', emptyHTML]);
|
const cli = runCLI(['--target=csharp', emptyHTML]);
|
||||||
const expectedResult = `await Playwright.InstallAsync();
|
const expectedResult = ` using var playwright = await Playwright.CreateAsync();
|
||||||
using var playwright = await Playwright.CreateAsync();
|
await using var browser = await playwright.${capitalize(browserName)}.LaunchAsync(new BrowserTypeLaunchOptions
|
||||||
await using var browser = await playwright.${capitalize(browserName)}.LaunchAsync(
|
{
|
||||||
${launchOptions(channel)}
|
${launchOptions(channel)}
|
||||||
);
|
});
|
||||||
var context = await browser.NewContextAsync();`;
|
var context = await browser.NewContextAsync();`;
|
||||||
await cli.waitFor(expectedResult).catch(e => e);
|
await cli.waitFor(expectedResult).catch(e => e);
|
||||||
expect(cli.text()).toContain(expectedResult);
|
expect(cli.text()).toContain(expectedResult);
|
||||||
});
|
});
|
||||||
|
|
@ -50,31 +50,34 @@ test('should print the correct context options for custom settings', async ({ br
|
||||||
'--viewport-size=1280,720',
|
'--viewport-size=1280,720',
|
||||||
'--target=csharp',
|
'--target=csharp',
|
||||||
emptyHTML]);
|
emptyHTML]);
|
||||||
const expectedResult = `await Playwright.InstallAsync();
|
const expectedResult = `
|
||||||
using var playwright = await Playwright.CreateAsync();
|
using var playwright = await Playwright.CreateAsync();
|
||||||
await using var browser = await playwright.${capitalize(browserName)}.LaunchAsync(
|
await using var browser = await playwright.${capitalize(browserName)}.LaunchAsync(new BrowserTypeLaunchOptions
|
||||||
${launchOptions(channel)},
|
{
|
||||||
proxy: new ProxySettings
|
${launchOptions(channel)}
|
||||||
{
|
Proxy = new ProxySettings
|
||||||
Server = "http://myproxy:3128",
|
{
|
||||||
}
|
Server = "http://myproxy:3128",
|
||||||
);
|
},
|
||||||
var context = await browser.NewContextAsync(
|
});
|
||||||
viewport: new ViewportSize
|
var context = await browser.NewContextAsync(new BrowserNewContextOptions
|
||||||
{
|
{
|
||||||
Width = 1280,
|
ViewportSize = new ViewportSize
|
||||||
Height = 720,
|
{
|
||||||
},
|
Width = 1280,
|
||||||
geolocation: new Geolocation
|
Height = 720,
|
||||||
{
|
},
|
||||||
Latitude = 37.819722m,
|
Geolocation = new Geolocation
|
||||||
Longitude = -122.478611m,
|
{
|
||||||
},
|
Latitude = 37.819722m,
|
||||||
permissions: new[] { ContextPermission.Geolocation },
|
Longitude = -122.478611m,
|
||||||
userAgent: "hardkodemium",
|
},
|
||||||
locale: "es",
|
Permissions = new[] { ContextPermission.Geolocation },
|
||||||
colorScheme: ColorScheme.Dark,
|
UserAgent = "hardkodemium",
|
||||||
timezoneId: "Europe/Rome");`;
|
Locale = "es",
|
||||||
|
ColorScheme = ColorScheme.Dark,
|
||||||
|
TimezoneId = "Europe/Rome",
|
||||||
|
});`;
|
||||||
await cli.waitFor(expectedResult);
|
await cli.waitFor(expectedResult);
|
||||||
expect(cli.text()).toContain(expectedResult);
|
expect(cli.text()).toContain(expectedResult);
|
||||||
});
|
});
|
||||||
|
|
@ -83,12 +86,13 @@ test('should print the correct context options when using a device', async ({ br
|
||||||
test.skip(browserName !== 'chromium');
|
test.skip(browserName !== 'chromium');
|
||||||
|
|
||||||
const cli = runCLI(['--device=Pixel 2', '--target=csharp', emptyHTML]);
|
const cli = runCLI(['--device=Pixel 2', '--target=csharp', emptyHTML]);
|
||||||
const expectedResult = `await Playwright.InstallAsync();
|
const expectedResult = `
|
||||||
using var playwright = await Playwright.CreateAsync();
|
using var playwright = await Playwright.CreateAsync();
|
||||||
await using var browser = await playwright.Chromium.LaunchAsync(
|
await using var browser = await playwright.${capitalize(browserName)}.LaunchAsync(new BrowserTypeLaunchOptions
|
||||||
${launchOptions(channel)}
|
{
|
||||||
);
|
${launchOptions(channel)}
|
||||||
var context = await browser.NewContextAsync(playwright.Devices["Pixel 2"]);`;
|
});
|
||||||
|
var context = await browser.NewContextAsync(playwright.Devices["Pixel 2"]);`;
|
||||||
await cli.waitFor(expectedResult);
|
await cli.waitFor(expectedResult);
|
||||||
expect(cli.text()).toContain(expectedResult);
|
expect(cli.text()).toContain(expectedResult);
|
||||||
});
|
});
|
||||||
|
|
@ -107,33 +111,34 @@ test('should print the correct context options when using a device and additiona
|
||||||
'--viewport-size=1280,720',
|
'--viewport-size=1280,720',
|
||||||
'--target=csharp',
|
'--target=csharp',
|
||||||
emptyHTML]);
|
emptyHTML]);
|
||||||
const expectedResult = `await Playwright.InstallAsync();
|
const expectedResult = `
|
||||||
using var playwright = await Playwright.CreateAsync();
|
using var playwright = await Playwright.CreateAsync();
|
||||||
await using var browser = await playwright.Webkit.LaunchAsync(
|
await using var browser = await playwright.${capitalize(browserName)}.LaunchAsync(new BrowserTypeLaunchOptions
|
||||||
${launchOptions(channel)},
|
{
|
||||||
proxy: new ProxySettings
|
${launchOptions(channel)}
|
||||||
{
|
Proxy = new ProxySettings
|
||||||
Server = "http://myproxy:3128",
|
{
|
||||||
}
|
Server = "http://myproxy:3128",
|
||||||
);
|
},
|
||||||
var context = await browser.NewContextAsync(new BrowserContextOptions(playwright.Devices["iPhone 11"])
|
});
|
||||||
{
|
var context = await browser.NewContextAsync(new BrowserNewContextOptions(playwright.Devices["iPhone 11"])
|
||||||
UserAgent = "hardkodemium",
|
{
|
||||||
Viewport = new ViewportSize
|
UserAgent = "hardkodemium",
|
||||||
{
|
ViewportSize = new ViewportSize
|
||||||
Width = 1280,
|
{
|
||||||
Height = 720,
|
Width = 1280,
|
||||||
},
|
Height = 720,
|
||||||
Geolocation = new Geolocation
|
},
|
||||||
{
|
Geolocation = new Geolocation
|
||||||
Latitude = 37.819722m,
|
{
|
||||||
Longitude = -122.478611m,
|
Latitude = 37.819722m,
|
||||||
},
|
Longitude = -122.478611m,
|
||||||
Permissions = new[] { ContextPermission.Geolocation },
|
},
|
||||||
Locale = "es",
|
Permissions = new[] { ContextPermission.Geolocation },
|
||||||
ColorScheme = ColorScheme.Dark,
|
Locale = "es",
|
||||||
TimezoneId = "Europe/Rome",
|
ColorScheme = ColorScheme.Dark,
|
||||||
});`;
|
TimezoneId = "Europe/Rome",
|
||||||
|
});`;
|
||||||
|
|
||||||
await cli.waitFor(expectedResult);
|
await cli.waitFor(expectedResult);
|
||||||
expect(cli.text()).toContain(expectedResult);
|
expect(cli.text()).toContain(expectedResult);
|
||||||
|
|
@ -144,18 +149,22 @@ test('should print load/save storageState', async ({ browserName, channel, runCL
|
||||||
const saveFileName = testInfo.outputPath('save.json');
|
const saveFileName = testInfo.outputPath('save.json');
|
||||||
await fs.promises.writeFile(loadFileName, JSON.stringify({ cookies: [], origins: [] }), 'utf8');
|
await fs.promises.writeFile(loadFileName, JSON.stringify({ cookies: [], origins: [] }), 'utf8');
|
||||||
const cli = runCLI([`--load-storage=${loadFileName}`, `--save-storage=${saveFileName}`, '--target=csharp', emptyHTML]);
|
const cli = runCLI([`--load-storage=${loadFileName}`, `--save-storage=${saveFileName}`, '--target=csharp', emptyHTML]);
|
||||||
const expectedResult1 = `await Playwright.InstallAsync();
|
const expectedResult1 = `
|
||||||
using var playwright = await Playwright.CreateAsync();
|
using var playwright = await Playwright.CreateAsync();
|
||||||
await using var browser = await playwright.${capitalize(browserName)}.LaunchAsync(
|
await using var browser = await playwright.${capitalize(browserName)}.LaunchAsync(new BrowserTypeLaunchOptions
|
||||||
${launchOptions(channel)}
|
{
|
||||||
);
|
${launchOptions(channel)}
|
||||||
var context = await browser.NewContextAsync(
|
});
|
||||||
storageState: "${loadFileName}");`;
|
var context = await browser.NewContextAsync(new BrowserNewContextOptions
|
||||||
|
{
|
||||||
|
StorageStatePath = "${loadFileName}",
|
||||||
|
});`;
|
||||||
await cli.waitFor(expectedResult1);
|
await cli.waitFor(expectedResult1);
|
||||||
|
|
||||||
const expectedResult2 = `
|
const expectedResult2 = `
|
||||||
// ---------------------
|
await context.StorageStateAsync(new BrowserContextStorageStateOptions
|
||||||
await context.StorageStateAsync(path: "${saveFileName}");
|
{
|
||||||
|
Path = "${saveFileName}"
|
||||||
|
});
|
||||||
`;
|
`;
|
||||||
await cli.waitFor(expectedResult2);
|
await cli.waitFor(expectedResult2);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue