mirror of
https://github.com/TheBinaryNinja/tvapp2.git
synced 2026-06-04 17:55:41 -04:00
build: push tvapp v2 docker files
This commit is contained in:
294
node_modules/playwright-core/lib/server/codegen/csharp.js
generated
vendored
Normal file
294
node_modules/playwright-core/lib/server/codegen/csharp.js
generated
vendored
Normal file
@@ -0,0 +1,294 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.CSharpLanguageGenerator = void 0;
|
||||
var _language = require("./language");
|
||||
var _utils = require("../../utils");
|
||||
var _deviceDescriptors = require("../deviceDescriptors");
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
class CSharpLanguageGenerator {
|
||||
constructor(mode) {
|
||||
this.id = void 0;
|
||||
this.groupName = '.NET C#';
|
||||
this.name = void 0;
|
||||
this.highlighter = 'csharp';
|
||||
this._mode = void 0;
|
||||
if (mode === 'library') {
|
||||
this.name = 'Library';
|
||||
this.id = 'csharp';
|
||||
} else if (mode === 'mstest') {
|
||||
this.name = 'MSTest';
|
||||
this.id = 'csharp-mstest';
|
||||
} else if (mode === 'nunit') {
|
||||
this.name = 'NUnit';
|
||||
this.id = 'csharp-nunit';
|
||||
} else {
|
||||
throw new Error(`Unknown C# language mode: ${mode}`);
|
||||
}
|
||||
this._mode = mode;
|
||||
}
|
||||
generateAction(actionInContext) {
|
||||
const action = this._generateActionInner(actionInContext);
|
||||
if (action) return action;
|
||||
return '';
|
||||
}
|
||||
_generateActionInner(actionInContext) {
|
||||
const action = actionInContext.action;
|
||||
if (this._mode !== 'library' && (action.name === 'openPage' || action.name === 'closePage')) return '';
|
||||
let pageAlias = actionInContext.frame.pageAlias;
|
||||
if (this._mode !== 'library') pageAlias = pageAlias.replace('page', 'Page');
|
||||
const formatter = new CSharpFormatter(this._mode === 'library' ? 0 : 8);
|
||||
if (action.name === 'openPage') {
|
||||
formatter.add(`var ${pageAlias} = await context.NewPageAsync();`);
|
||||
if (action.url && action.url !== 'about:blank' && action.url !== 'chrome://newtab/') formatter.add(`await ${pageAlias}.GotoAsync(${quote(action.url)});`);
|
||||
return formatter.format();
|
||||
}
|
||||
const locators = actionInContext.frame.framePath.map(selector => `.${this._asLocator(selector)}.ContentFrame`);
|
||||
const subject = `${pageAlias}${locators.join('')}`;
|
||||
const signals = (0, _language.toSignalMap)(action);
|
||||
if (signals.dialog) {
|
||||
formatter.add(` void ${pageAlias}_Dialog${signals.dialog.dialogAlias}_EventHandler(object sender, IDialog dialog)
|
||||
{
|
||||
Console.WriteLine($"Dialog message: {dialog.Message}");
|
||||
dialog.DismissAsync();
|
||||
${pageAlias}.Dialog -= ${pageAlias}_Dialog${signals.dialog.dialogAlias}_EventHandler;
|
||||
}
|
||||
${pageAlias}.Dialog += ${pageAlias}_Dialog${signals.dialog.dialogAlias}_EventHandler;`);
|
||||
}
|
||||
const lines = [];
|
||||
lines.push(this._generateActionCall(subject, actionInContext));
|
||||
if (signals.download) {
|
||||
lines.unshift(`var download${signals.download.downloadAlias} = await ${pageAlias}.RunAndWaitForDownloadAsync(async () =>\n{`);
|
||||
lines.push(`});`);
|
||||
}
|
||||
if (signals.popup) {
|
||||
lines.unshift(`var ${signals.popup.popupAlias} = await ${pageAlias}.RunAndWaitForPopupAsync(async () =>\n{`);
|
||||
lines.push(`});`);
|
||||
}
|
||||
for (const line of lines) formatter.add(line);
|
||||
return formatter.format();
|
||||
}
|
||||
_generateActionCall(subject, actionInContext) {
|
||||
const action = actionInContext.action;
|
||||
switch (action.name) {
|
||||
case 'openPage':
|
||||
throw Error('Not reached');
|
||||
case 'closePage':
|
||||
return `await ${subject}.CloseAsync();`;
|
||||
case 'click':
|
||||
{
|
||||
let method = 'Click';
|
||||
if (action.clickCount === 2) method = 'DblClick';
|
||||
const options = (0, _language.toClickOptionsForSourceCode)(action);
|
||||
if (!Object.entries(options).length) return `await ${subject}.${this._asLocator(action.selector)}.${method}Async();`;
|
||||
const optionsString = formatObject(options, ' ', 'Locator' + method + 'Options');
|
||||
return `await ${subject}.${this._asLocator(action.selector)}.${method}Async(${optionsString});`;
|
||||
}
|
||||
case 'check':
|
||||
return `await ${subject}.${this._asLocator(action.selector)}.CheckAsync();`;
|
||||
case 'uncheck':
|
||||
return `await ${subject}.${this._asLocator(action.selector)}.UncheckAsync();`;
|
||||
case 'fill':
|
||||
return `await ${subject}.${this._asLocator(action.selector)}.FillAsync(${quote(action.text)});`;
|
||||
case 'setInputFiles':
|
||||
return `await ${subject}.${this._asLocator(action.selector)}.SetInputFilesAsync(${formatObject(action.files)});`;
|
||||
case 'press':
|
||||
{
|
||||
const modifiers = (0, _language.toKeyboardModifiers)(action.modifiers);
|
||||
const shortcut = [...modifiers, action.key].join('+');
|
||||
return `await ${subject}.${this._asLocator(action.selector)}.PressAsync(${quote(shortcut)});`;
|
||||
}
|
||||
case 'navigate':
|
||||
return `await ${subject}.GotoAsync(${quote(action.url)});`;
|
||||
case 'select':
|
||||
return `await ${subject}.${this._asLocator(action.selector)}.SelectOptionAsync(${formatObject(action.options)});`;
|
||||
case 'assertText':
|
||||
return `await Expect(${subject}.${this._asLocator(action.selector)}).${action.substring ? 'ToContainTextAsync' : 'ToHaveTextAsync'}(${quote(action.text)});`;
|
||||
case 'assertChecked':
|
||||
return `await Expect(${subject}.${this._asLocator(action.selector)})${action.checked ? '' : '.Not'}.ToBeCheckedAsync();`;
|
||||
case 'assertVisible':
|
||||
return `await Expect(${subject}.${this._asLocator(action.selector)}).ToBeVisibleAsync();`;
|
||||
case 'assertValue':
|
||||
{
|
||||
const assertion = action.value ? `ToHaveValueAsync(${quote(action.value)})` : `ToBeEmptyAsync()`;
|
||||
return `await Expect(${subject}.${this._asLocator(action.selector)}).${assertion};`;
|
||||
}
|
||||
case 'assertSnapshot':
|
||||
return `await Expect(${subject}.${this._asLocator(action.selector)}).ToMatchAriaSnapshotAsync(${quote(action.snapshot)});`;
|
||||
}
|
||||
}
|
||||
_asLocator(selector) {
|
||||
return (0, _utils.asLocator)('csharp', selector);
|
||||
}
|
||||
generateHeader(options) {
|
||||
if (this._mode === 'library') return this.generateStandaloneHeader(options);
|
||||
return this.generateTestRunnerHeader(options);
|
||||
}
|
||||
generateStandaloneHeader(options) {
|
||||
const formatter = new CSharpFormatter(0);
|
||||
formatter.add(`
|
||||
using Microsoft.Playwright;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
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)});`);
|
||||
if (options.contextOptions.recordHar) formatter.add(` await context.RouteFromHARAsync(${quote(options.contextOptions.recordHar.path)});`);
|
||||
formatter.newLine();
|
||||
return formatter.format();
|
||||
}
|
||||
generateTestRunnerHeader(options) {
|
||||
const formatter = new CSharpFormatter(0);
|
||||
formatter.add(`
|
||||
using Microsoft.Playwright.${this._mode === 'nunit' ? 'NUnit' : 'MSTest'};
|
||||
using Microsoft.Playwright;
|
||||
|
||||
${this._mode === 'nunit' ? `[Parallelizable(ParallelScope.Self)]
|
||||
[TestFixture]` : '[TestClass]'}
|
||||
public class Tests : PageTest
|
||||
{`);
|
||||
const formattedContextOptions = formatContextOptions(options.contextOptions, options.deviceName);
|
||||
if (formattedContextOptions) {
|
||||
formatter.add(`public override BrowserNewContextOptions ContextOptions()
|
||||
{
|
||||
return ${formattedContextOptions};
|
||||
}`);
|
||||
formatter.newLine();
|
||||
}
|
||||
formatter.add(` [${this._mode === 'nunit' ? 'Test' : 'TestMethod'}]
|
||||
public async Task MyTest()
|
||||
{`);
|
||||
if (options.contextOptions.recordHar) formatter.add(` await context.RouteFromHARAsync(${quote(options.contextOptions.recordHar.path)});`);
|
||||
return formatter.format();
|
||||
}
|
||||
generateFooter(saveStorage) {
|
||||
const offset = this._mode === 'library' ? '' : ' ';
|
||||
let storageStateLine = saveStorage ? `\n${offset}await context.StorageStateAsync(new BrowserContextStorageStateOptions\n${offset}{\n${offset} Path = ${quote(saveStorage)}\n${offset}});\n` : '';
|
||||
if (this._mode !== 'library') storageStateLine += ` }\n}\n`;
|
||||
return storageStateLine;
|
||||
}
|
||||
}
|
||||
exports.CSharpLanguageGenerator = CSharpLanguageGenerator;
|
||||
function formatObject(value, indent = ' ', name = '') {
|
||||
if (typeof value === 'string') {
|
||||
if (['permissions', 'colorScheme', 'modifiers', 'button', 'recordHarContent', 'recordHarMode', 'serviceWorkers'].includes(name)) return `${getClassName(name)}.${toPascal(value)}`;
|
||||
return quote(value);
|
||||
}
|
||||
if (Array.isArray(value)) return `new[] { ${value.map(o => formatObject(o, indent, name)).join(', ')} }`;
|
||||
if (typeof value === 'object') {
|
||||
const keys = Object.keys(value).filter(key => value[key] !== undefined).sort();
|
||||
if (!keys.length) return name ? `new ${getClassName(name)}` : '';
|
||||
const tokens = [];
|
||||
for (const key of keys) {
|
||||
const property = getPropertyName(key);
|
||||
tokens.push(`${property} = ${formatObject(value[key], indent, key)},`);
|
||||
}
|
||||
if (name) return `new ${getClassName(name)}\n{\n${indent}${tokens.join(`\n${indent}`)}\n${indent}}`;
|
||||
return `{\n${indent}${tokens.join(`\n${indent}`)}\n${indent}}`;
|
||||
}
|
||||
if (name === 'latitude' || name === 'longitude') return String(value) + 'm';
|
||||
return String(value);
|
||||
}
|
||||
function getClassName(value) {
|
||||
switch (value) {
|
||||
case 'viewport':
|
||||
return 'ViewportSize';
|
||||
case 'proxy':
|
||||
return 'ProxySettings';
|
||||
case 'permissions':
|
||||
return 'ContextPermission';
|
||||
case 'modifiers':
|
||||
return 'KeyboardModifier';
|
||||
case 'button':
|
||||
return 'MouseButton';
|
||||
case 'recordHarMode':
|
||||
return 'HarMode';
|
||||
case 'recordHarContent':
|
||||
return 'HarContentPolicy';
|
||||
case 'serviceWorkers':
|
||||
return 'ServiceWorkerPolicy';
|
||||
default:
|
||||
return toPascal(value);
|
||||
}
|
||||
}
|
||||
function getPropertyName(key) {
|
||||
switch (key) {
|
||||
case 'storageState':
|
||||
return 'StorageStatePath';
|
||||
case 'viewport':
|
||||
return 'ViewportSize';
|
||||
default:
|
||||
return toPascal(key);
|
||||
}
|
||||
}
|
||||
function toPascal(value) {
|
||||
return value[0].toUpperCase() + value.slice(1);
|
||||
}
|
||||
function formatContextOptions(contextOptions, deviceName) {
|
||||
let options = {
|
||||
...contextOptions
|
||||
};
|
||||
// recordHAR is replaced with routeFromHAR in the generated code.
|
||||
delete options.recordHar;
|
||||
const device = deviceName && _deviceDescriptors.deviceDescriptors[deviceName];
|
||||
if (!device) {
|
||||
if (!Object.entries(options).length) return '';
|
||||
return formatObject(options, ' ', 'BrowserNewContextOptions');
|
||||
}
|
||||
options = (0, _language.sanitizeDeviceOptions)(device, options);
|
||||
if (!Object.entries(options).length) return `playwright.Devices[${quote(deviceName)}]`;
|
||||
return formatObject(options, ' ', `BrowserNewContextOptions(playwright.Devices[${quote(deviceName)}])`);
|
||||
}
|
||||
class CSharpFormatter {
|
||||
constructor(offset = 0) {
|
||||
this._baseIndent = void 0;
|
||||
this._baseOffset = void 0;
|
||||
this._lines = [];
|
||||
this._baseIndent = ' '.repeat(4);
|
||||
this._baseOffset = ' '.repeat(offset);
|
||||
}
|
||||
prepend(text) {
|
||||
this._lines = text.trim().split('\n').map(line => line.trim()).concat(this._lines);
|
||||
}
|
||||
add(text) {
|
||||
this._lines.push(...text.trim().split('\n').map(line => line.trim()));
|
||||
}
|
||||
newLine() {
|
||||
this._lines.push('');
|
||||
}
|
||||
format() {
|
||||
let spaces = '';
|
||||
let previousLine = '';
|
||||
return this._lines.map(line => {
|
||||
if (line === '') return line;
|
||||
if (line.startsWith('}') || line.startsWith(']') || line.includes('});') || line === ');') spaces = spaces.substring(this._baseIndent.length);
|
||||
const extraSpaces = /^(for|while|if).*\(.*\)$/.test(previousLine) ? this._baseIndent : '';
|
||||
previousLine = line;
|
||||
line = spaces + extraSpaces + line;
|
||||
if (line.endsWith('{') || line.endsWith('[') || line.endsWith('(')) spaces += this._baseIndent;
|
||||
if (line.endsWith('));')) spaces = spaces.substring(this._baseIndent.length);
|
||||
return this._baseOffset + line;
|
||||
}).join('\n');
|
||||
}
|
||||
}
|
||||
function quote(text) {
|
||||
return (0, _utils.escapeWithQuotes)(text, '\"');
|
||||
}
|
||||
232
node_modules/playwright-core/lib/server/codegen/java.js
generated
vendored
Normal file
232
node_modules/playwright-core/lib/server/codegen/java.js
generated
vendored
Normal file
@@ -0,0 +1,232 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.JavaLanguageGenerator = void 0;
|
||||
var _language = require("./language");
|
||||
var _deviceDescriptors = require("../deviceDescriptors");
|
||||
var _javascript = require("./javascript");
|
||||
var _utils = require("../../utils");
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
class JavaLanguageGenerator {
|
||||
constructor(mode) {
|
||||
this.id = void 0;
|
||||
this.groupName = 'Java';
|
||||
this.name = void 0;
|
||||
this.highlighter = 'java';
|
||||
this._mode = void 0;
|
||||
if (mode === 'library') {
|
||||
this.name = 'Library';
|
||||
this.id = 'java';
|
||||
} else if (mode === 'junit') {
|
||||
this.name = 'JUnit';
|
||||
this.id = 'java-junit';
|
||||
} else {
|
||||
throw new Error(`Unknown Java language mode: ${mode}`);
|
||||
}
|
||||
this._mode = mode;
|
||||
}
|
||||
generateAction(actionInContext) {
|
||||
const action = actionInContext.action;
|
||||
const pageAlias = actionInContext.frame.pageAlias;
|
||||
const offset = this._mode === 'junit' ? 4 : 6;
|
||||
const formatter = new _javascript.JavaScriptFormatter(offset);
|
||||
if (this._mode !== 'library' && (action.name === 'openPage' || action.name === 'closePage')) return '';
|
||||
if (action.name === 'openPage') {
|
||||
formatter.add(`Page ${pageAlias} = context.newPage();`);
|
||||
if (action.url && action.url !== 'about:blank' && action.url !== 'chrome://newtab/') formatter.add(`${pageAlias}.navigate(${quote(action.url)});`);
|
||||
return formatter.format();
|
||||
}
|
||||
const locators = actionInContext.frame.framePath.map(selector => `.${this._asLocator(selector, false)}.contentFrame()`);
|
||||
const subject = `${pageAlias}${locators.join('')}`;
|
||||
const signals = (0, _language.toSignalMap)(action);
|
||||
if (signals.dialog) {
|
||||
formatter.add(` ${pageAlias}.onceDialog(dialog -> {
|
||||
System.out.println(String.format("Dialog message: %s", dialog.message()));
|
||||
dialog.dismiss();
|
||||
});`);
|
||||
}
|
||||
let code = this._generateActionCall(subject, actionInContext, !!actionInContext.frame.framePath.length);
|
||||
if (signals.popup) {
|
||||
code = `Page ${signals.popup.popupAlias} = ${pageAlias}.waitForPopup(() -> {
|
||||
${code}
|
||||
});`;
|
||||
}
|
||||
if (signals.download) {
|
||||
code = `Download download${signals.download.downloadAlias} = ${pageAlias}.waitForDownload(() -> {
|
||||
${code}
|
||||
});`;
|
||||
}
|
||||
formatter.add(code);
|
||||
return formatter.format();
|
||||
}
|
||||
_generateActionCall(subject, actionInContext, inFrameLocator) {
|
||||
const action = actionInContext.action;
|
||||
switch (action.name) {
|
||||
case 'openPage':
|
||||
throw Error('Not reached');
|
||||
case 'closePage':
|
||||
return `${subject}.close();`;
|
||||
case 'click':
|
||||
{
|
||||
let method = 'click';
|
||||
if (action.clickCount === 2) method = 'dblclick';
|
||||
const options = (0, _language.toClickOptionsForSourceCode)(action);
|
||||
const optionsText = formatClickOptions(options);
|
||||
return `${subject}.${this._asLocator(action.selector, inFrameLocator)}.${method}(${optionsText});`;
|
||||
}
|
||||
case 'check':
|
||||
return `${subject}.${this._asLocator(action.selector, inFrameLocator)}.check();`;
|
||||
case 'uncheck':
|
||||
return `${subject}.${this._asLocator(action.selector, inFrameLocator)}.uncheck();`;
|
||||
case 'fill':
|
||||
return `${subject}.${this._asLocator(action.selector, inFrameLocator)}.fill(${quote(action.text)});`;
|
||||
case 'setInputFiles':
|
||||
return `${subject}.${this._asLocator(action.selector, inFrameLocator)}.setInputFiles(${formatPath(action.files.length === 1 ? action.files[0] : action.files)});`;
|
||||
case 'press':
|
||||
{
|
||||
const modifiers = (0, _language.toKeyboardModifiers)(action.modifiers);
|
||||
const shortcut = [...modifiers, action.key].join('+');
|
||||
return `${subject}.${this._asLocator(action.selector, inFrameLocator)}.press(${quote(shortcut)});`;
|
||||
}
|
||||
case 'navigate':
|
||||
return `${subject}.navigate(${quote(action.url)});`;
|
||||
case 'select':
|
||||
return `${subject}.${this._asLocator(action.selector, inFrameLocator)}.selectOption(${formatSelectOption(action.options.length === 1 ? action.options[0] : action.options)});`;
|
||||
case 'assertText':
|
||||
return `assertThat(${subject}.${this._asLocator(action.selector, inFrameLocator)}).${action.substring ? 'containsText' : 'hasText'}(${quote(action.text)});`;
|
||||
case 'assertChecked':
|
||||
return `assertThat(${subject}.${this._asLocator(action.selector, inFrameLocator)})${action.checked ? '' : '.not()'}.isChecked();`;
|
||||
case 'assertVisible':
|
||||
return `assertThat(${subject}.${this._asLocator(action.selector, inFrameLocator)}).isVisible();`;
|
||||
case 'assertValue':
|
||||
{
|
||||
const assertion = action.value ? `hasValue(${quote(action.value)})` : `isEmpty()`;
|
||||
return `assertThat(${subject}.${this._asLocator(action.selector, inFrameLocator)}).${assertion};`;
|
||||
}
|
||||
case 'assertSnapshot':
|
||||
return `assertThat(${subject}.${this._asLocator(action.selector, inFrameLocator)}).matchesAriaSnapshot(${quote(action.snapshot)});`;
|
||||
}
|
||||
}
|
||||
_asLocator(selector, inFrameLocator) {
|
||||
return (0, _utils.asLocator)('java', selector, inFrameLocator);
|
||||
}
|
||||
generateHeader(options) {
|
||||
const formatter = new _javascript.JavaScriptFormatter();
|
||||
if (this._mode === 'junit') {
|
||||
formatter.add(`
|
||||
import com.microsoft.playwright.junit.UsePlaywright;
|
||||
import com.microsoft.playwright.Page;
|
||||
import com.microsoft.playwright.options.*;
|
||||
|
||||
import org.junit.jupiter.api.*;
|
||||
import static com.microsoft.playwright.assertions.PlaywrightAssertions.*;
|
||||
|
||||
@UsePlaywright
|
||||
public class TestExample {
|
||||
@Test
|
||||
void test(Page page) {`);
|
||||
return formatter.format();
|
||||
}
|
||||
formatter.add(`
|
||||
import com.microsoft.playwright.*;
|
||||
import com.microsoft.playwright.options.*;
|
||||
import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat;
|
||||
import java.util.*;
|
||||
|
||||
public class Example {
|
||||
public static void main(String[] args) {
|
||||
try (Playwright playwright = Playwright.create()) {
|
||||
Browser browser = playwright.${options.browserName}().launch(${formatLaunchOptions(options.launchOptions)});
|
||||
BrowserContext context = browser.newContext(${formatContextOptions(options.contextOptions, options.deviceName)});`);
|
||||
if (options.contextOptions.recordHar) formatter.add(` context.routeFromHAR(${quote(options.contextOptions.recordHar.path)});`);
|
||||
return formatter.format();
|
||||
}
|
||||
generateFooter(saveStorage) {
|
||||
const storageStateLine = saveStorage ? `\n context.storageState(new BrowserContext.StorageStateOptions().setPath(${quote(saveStorage)}));\n` : '';
|
||||
if (this._mode === 'junit') {
|
||||
return `${storageStateLine} }
|
||||
}`;
|
||||
}
|
||||
return `${storageStateLine} }
|
||||
}
|
||||
}`;
|
||||
}
|
||||
}
|
||||
exports.JavaLanguageGenerator = JavaLanguageGenerator;
|
||||
function formatPath(files) {
|
||||
if (Array.isArray(files)) {
|
||||
if (files.length === 0) return 'new Path[0]';
|
||||
return `new Path[] {${files.map(s => 'Paths.get(' + quote(s) + ')').join(', ')}}`;
|
||||
}
|
||||
return `Paths.get(${quote(files)})`;
|
||||
}
|
||||
function formatSelectOption(options) {
|
||||
if (Array.isArray(options)) {
|
||||
if (options.length === 0) return 'new String[0]';
|
||||
return `new String[] {${options.map(s => quote(s)).join(', ')}}`;
|
||||
}
|
||||
return quote(options);
|
||||
}
|
||||
function formatLaunchOptions(options) {
|
||||
const lines = [];
|
||||
if (!Object.keys(options).filter(key => options[key] !== undefined).length) return '';
|
||||
lines.push('new BrowserType.LaunchOptions()');
|
||||
if (options.channel) lines.push(` .setChannel(${quote(options.channel)})`);
|
||||
if (typeof options.headless === 'boolean') lines.push(` .setHeadless(false)`);
|
||||
return lines.join('\n');
|
||||
}
|
||||
function formatContextOptions(contextOptions, deviceName) {
|
||||
const lines = [];
|
||||
if (!Object.keys(contextOptions).length && !deviceName) return '';
|
||||
const device = deviceName ? _deviceDescriptors.deviceDescriptors[deviceName] : {};
|
||||
const options = {
|
||||
...device,
|
||||
...contextOptions
|
||||
};
|
||||
lines.push('new Browser.NewContextOptions()');
|
||||
if (options.acceptDownloads) lines.push(` .setAcceptDownloads(true)`);
|
||||
if (options.bypassCSP) lines.push(` .setBypassCSP(true)`);
|
||||
if (options.colorScheme) lines.push(` .setColorScheme(ColorScheme.${options.colorScheme.toUpperCase()})`);
|
||||
if (options.deviceScaleFactor) lines.push(` .setDeviceScaleFactor(${options.deviceScaleFactor})`);
|
||||
if (options.geolocation) lines.push(` .setGeolocation(${options.geolocation.latitude}, ${options.geolocation.longitude})`);
|
||||
if (options.hasTouch) lines.push(` .setHasTouch(${options.hasTouch})`);
|
||||
if (options.isMobile) lines.push(` .setIsMobile(${options.isMobile})`);
|
||||
if (options.locale) lines.push(` .setLocale(${quote(options.locale)})`);
|
||||
if (options.proxy) lines.push(` .setProxy(new Proxy(${quote(options.proxy.server)}))`);
|
||||
if (options.serviceWorkers) lines.push(` .setServiceWorkers(ServiceWorkerPolicy.${options.serviceWorkers.toUpperCase()})`);
|
||||
if (options.storageState) lines.push(` .setStorageStatePath(Paths.get(${quote(options.storageState)}))`);
|
||||
if (options.timezoneId) lines.push(` .setTimezoneId(${quote(options.timezoneId)})`);
|
||||
if (options.userAgent) lines.push(` .setUserAgent(${quote(options.userAgent)})`);
|
||||
if (options.viewport) lines.push(` .setViewportSize(${options.viewport.width}, ${options.viewport.height})`);
|
||||
return lines.join('\n');
|
||||
}
|
||||
function formatClickOptions(options) {
|
||||
const lines = [];
|
||||
if (options.button) lines.push(` .setButton(MouseButton.${options.button.toUpperCase()})`);
|
||||
if (options.modifiers) lines.push(` .setModifiers(Arrays.asList(${options.modifiers.map(m => `KeyboardModifier.${m.toUpperCase()}`).join(', ')}))`);
|
||||
if (options.clickCount) lines.push(` .setClickCount(${options.clickCount})`);
|
||||
if (options.position) lines.push(` .setPosition(${options.position.x}, ${options.position.y})`);
|
||||
if (!lines.length) return '';
|
||||
lines.unshift(`new Locator.ClickOptions()`);
|
||||
return lines.join('\n');
|
||||
}
|
||||
function quote(text) {
|
||||
return (0, _utils.escapeWithQuotes)(text, '\"');
|
||||
}
|
||||
245
node_modules/playwright-core/lib/server/codegen/javascript.js
generated
vendored
Normal file
245
node_modules/playwright-core/lib/server/codegen/javascript.js
generated
vendored
Normal file
@@ -0,0 +1,245 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.JavaScriptLanguageGenerator = exports.JavaScriptFormatter = void 0;
|
||||
exports.quoteMultiline = quoteMultiline;
|
||||
var _language = require("./language");
|
||||
var _deviceDescriptors = require("../deviceDescriptors");
|
||||
var _utils = require("../../utils");
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
class JavaScriptLanguageGenerator {
|
||||
constructor(isTest) {
|
||||
this.id = void 0;
|
||||
this.groupName = 'Node.js';
|
||||
this.name = void 0;
|
||||
this.highlighter = 'javascript';
|
||||
this._isTest = void 0;
|
||||
this.id = isTest ? 'playwright-test' : 'javascript';
|
||||
this.name = isTest ? 'Test Runner' : 'Library';
|
||||
this._isTest = isTest;
|
||||
}
|
||||
generateAction(actionInContext) {
|
||||
const action = actionInContext.action;
|
||||
if (this._isTest && (action.name === 'openPage' || action.name === 'closePage')) return '';
|
||||
const pageAlias = actionInContext.frame.pageAlias;
|
||||
const formatter = new JavaScriptFormatter(2);
|
||||
if (action.name === 'openPage') {
|
||||
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)});`);
|
||||
return formatter.format();
|
||||
}
|
||||
const locators = actionInContext.frame.framePath.map(selector => `.${this._asLocator(selector)}.contentFrame()`);
|
||||
const subject = `${pageAlias}${locators.join('')}`;
|
||||
const signals = (0, _language.toSignalMap)(action);
|
||||
if (signals.dialog) {
|
||||
formatter.add(` ${pageAlias}.once('dialog', dialog => {
|
||||
console.log(\`Dialog message: $\{dialog.message()}\`);
|
||||
dialog.dismiss().catch(() => {});
|
||||
});`);
|
||||
}
|
||||
if (signals.popup) formatter.add(`const ${signals.popup.popupAlias}Promise = ${pageAlias}.waitForEvent('popup');`);
|
||||
if (signals.download) formatter.add(`const download${signals.download.downloadAlias}Promise = ${pageAlias}.waitForEvent('download');`);
|
||||
formatter.add(wrapWithStep(actionInContext.description, this._generateActionCall(subject, actionInContext)));
|
||||
if (signals.popup) formatter.add(`const ${signals.popup.popupAlias} = await ${signals.popup.popupAlias}Promise;`);
|
||||
if (signals.download) formatter.add(`const download${signals.download.downloadAlias} = await download${signals.download.downloadAlias}Promise;`);
|
||||
return formatter.format();
|
||||
}
|
||||
_generateActionCall(subject, actionInContext) {
|
||||
const action = actionInContext.action;
|
||||
switch (action.name) {
|
||||
case 'openPage':
|
||||
throw Error('Not reached');
|
||||
case 'closePage':
|
||||
return `await ${subject}.close();`;
|
||||
case 'click':
|
||||
{
|
||||
let method = 'click';
|
||||
if (action.clickCount === 2) method = 'dblclick';
|
||||
const options = (0, _language.toClickOptionsForSourceCode)(action);
|
||||
const optionsString = formatOptions(options, false);
|
||||
return `await ${subject}.${this._asLocator(action.selector)}.${method}(${optionsString});`;
|
||||
}
|
||||
case 'check':
|
||||
return `await ${subject}.${this._asLocator(action.selector)}.check();`;
|
||||
case 'uncheck':
|
||||
return `await ${subject}.${this._asLocator(action.selector)}.uncheck();`;
|
||||
case 'fill':
|
||||
return `await ${subject}.${this._asLocator(action.selector)}.fill(${quote(action.text)});`;
|
||||
case 'setInputFiles':
|
||||
return `await ${subject}.${this._asLocator(action.selector)}.setInputFiles(${formatObject(action.files.length === 1 ? action.files[0] : action.files)});`;
|
||||
case 'press':
|
||||
{
|
||||
const modifiers = (0, _language.toKeyboardModifiers)(action.modifiers);
|
||||
const shortcut = [...modifiers, action.key].join('+');
|
||||
return `await ${subject}.${this._asLocator(action.selector)}.press(${quote(shortcut)});`;
|
||||
}
|
||||
case 'navigate':
|
||||
return `await ${subject}.goto(${quote(action.url)});`;
|
||||
case 'select':
|
||||
return `await ${subject}.${this._asLocator(action.selector)}.selectOption(${formatObject(action.options.length === 1 ? action.options[0] : action.options)});`;
|
||||
case 'assertText':
|
||||
return `${this._isTest ? '' : '// '}await expect(${subject}.${this._asLocator(action.selector)}).${action.substring ? 'toContainText' : 'toHaveText'}(${quote(action.text)});`;
|
||||
case 'assertChecked':
|
||||
return `${this._isTest ? '' : '// '}await expect(${subject}.${this._asLocator(action.selector)})${action.checked ? '' : '.not'}.toBeChecked();`;
|
||||
case 'assertVisible':
|
||||
return `${this._isTest ? '' : '// '}await expect(${subject}.${this._asLocator(action.selector)}).toBeVisible();`;
|
||||
case 'assertValue':
|
||||
{
|
||||
const assertion = action.value ? `toHaveValue(${quote(action.value)})` : `toBeEmpty()`;
|
||||
return `${this._isTest ? '' : '// '}await expect(${subject}.${this._asLocator(action.selector)}).${assertion};`;
|
||||
}
|
||||
case 'assertSnapshot':
|
||||
return `${this._isTest ? '' : '// '}await expect(${subject}.${this._asLocator(action.selector)}).toMatchAriaSnapshot(${quoteMultiline(action.snapshot)});`;
|
||||
}
|
||||
}
|
||||
_asLocator(selector) {
|
||||
return (0, _utils.asLocator)('javascript', selector);
|
||||
}
|
||||
generateHeader(options) {
|
||||
if (this._isTest) return this.generateTestHeader(options);
|
||||
return this.generateStandaloneHeader(options);
|
||||
}
|
||||
generateFooter(saveStorage) {
|
||||
if (this._isTest) return this.generateTestFooter(saveStorage);
|
||||
return this.generateStandaloneFooter(saveStorage);
|
||||
}
|
||||
generateTestHeader(options) {
|
||||
const formatter = new JavaScriptFormatter();
|
||||
const useText = formatContextOptions(options.contextOptions, options.deviceName, this._isTest);
|
||||
formatter.add(`
|
||||
import { test, expect${options.deviceName ? ', devices' : ''} } from '@playwright/test';
|
||||
${useText ? '\ntest.use(' + useText + ');\n' : ''}
|
||||
test('test', async ({ page }) => {`);
|
||||
if (options.contextOptions.recordHar) formatter.add(` await page.routeFromHAR(${quote(options.contextOptions.recordHar.path)});`);
|
||||
return formatter.format();
|
||||
}
|
||||
generateTestFooter(saveStorage) {
|
||||
return `});`;
|
||||
}
|
||||
generateStandaloneHeader(options) {
|
||||
const formatter = new JavaScriptFormatter();
|
||||
formatter.add(`
|
||||
const { ${options.browserName}${options.deviceName ? ', devices' : ''} } = require('playwright');
|
||||
|
||||
(async () => {
|
||||
const browser = await ${options.browserName}.launch(${formatObjectOrVoid(options.launchOptions)});
|
||||
const context = await browser.newContext(${formatContextOptions(options.contextOptions, options.deviceName, false)});`);
|
||||
if (options.contextOptions.recordHar) formatter.add(` await context.routeFromHAR(${quote(options.contextOptions.recordHar.path)});`);
|
||||
return formatter.format();
|
||||
}
|
||||
generateStandaloneFooter(saveStorage) {
|
||||
const storageStateLine = saveStorage ? `\n await context.storageState({ path: ${quote(saveStorage)} });` : '';
|
||||
return `\n // ---------------------${storageStateLine}
|
||||
await context.close();
|
||||
await browser.close();
|
||||
})();`;
|
||||
}
|
||||
}
|
||||
exports.JavaScriptLanguageGenerator = JavaScriptLanguageGenerator;
|
||||
function formatOptions(value, hasArguments) {
|
||||
const keys = Object.keys(value);
|
||||
if (!keys.length) return '';
|
||||
return (hasArguments ? ', ' : '') + formatObject(value);
|
||||
}
|
||||
function formatObject(value, indent = ' ') {
|
||||
if (typeof value === 'string') return quote(value);
|
||||
if (Array.isArray(value)) return `[${value.map(o => formatObject(o)).join(', ')}]`;
|
||||
if (typeof value === 'object') {
|
||||
const keys = Object.keys(value).filter(key => value[key] !== undefined).sort();
|
||||
if (!keys.length) return '{}';
|
||||
const tokens = [];
|
||||
for (const key of keys) tokens.push(`${key}: ${formatObject(value[key])}`);
|
||||
return `{\n${indent}${tokens.join(`,\n${indent}`)}\n}`;
|
||||
}
|
||||
return String(value);
|
||||
}
|
||||
function formatObjectOrVoid(value, indent = ' ') {
|
||||
const result = formatObject(value, indent);
|
||||
return result === '{}' ? '' : result;
|
||||
}
|
||||
function formatContextOptions(options, deviceName, isTest) {
|
||||
const device = deviceName && _deviceDescriptors.deviceDescriptors[deviceName];
|
||||
// recordHAR is replaced with routeFromHAR in the generated code.
|
||||
options = {
|
||||
...options,
|
||||
recordHar: undefined
|
||||
};
|
||||
if (!device) return formatObjectOrVoid(options);
|
||||
// Filter out all the properties from the device descriptor.
|
||||
let serializedObject = formatObjectOrVoid((0, _language.sanitizeDeviceOptions)(device, options));
|
||||
// When there are no additional context options, we still want to spread the device inside.
|
||||
if (!serializedObject) serializedObject = '{\n}';
|
||||
const lines = serializedObject.split('\n');
|
||||
lines.splice(1, 0, `...devices[${quote(deviceName)}],`);
|
||||
return lines.join('\n');
|
||||
}
|
||||
class JavaScriptFormatter {
|
||||
constructor(offset = 0) {
|
||||
this._baseIndent = void 0;
|
||||
this._baseOffset = void 0;
|
||||
this._lines = [];
|
||||
this._baseIndent = ' '.repeat(2);
|
||||
this._baseOffset = ' '.repeat(offset);
|
||||
}
|
||||
prepend(text) {
|
||||
const trim = isMultilineString(text) ? line => line : line => line.trim();
|
||||
this._lines = text.trim().split('\n').map(trim).concat(this._lines);
|
||||
}
|
||||
add(text) {
|
||||
const trim = isMultilineString(text) ? line => line : line => line.trim();
|
||||
this._lines.push(...text.trim().split('\n').map(trim));
|
||||
}
|
||||
newLine() {
|
||||
this._lines.push('');
|
||||
}
|
||||
format() {
|
||||
let spaces = '';
|
||||
let previousLine = '';
|
||||
return this._lines.map(line => {
|
||||
if (line === '') return line;
|
||||
if (line.startsWith('}') || line.startsWith(']')) spaces = spaces.substring(this._baseIndent.length);
|
||||
const extraSpaces = /^(for|while|if|try).*\(.*\)$/.test(previousLine) ? this._baseIndent : '';
|
||||
previousLine = line;
|
||||
const callCarryOver = line.startsWith('.set');
|
||||
line = spaces + extraSpaces + (callCarryOver ? this._baseIndent : '') + line;
|
||||
if (line.endsWith('{') || line.endsWith('[')) spaces += this._baseIndent;
|
||||
return this._baseOffset + line;
|
||||
}).join('\n');
|
||||
}
|
||||
}
|
||||
exports.JavaScriptFormatter = JavaScriptFormatter;
|
||||
function quote(text) {
|
||||
return (0, _utils.escapeWithQuotes)(text, '\'');
|
||||
}
|
||||
function wrapWithStep(description, body) {
|
||||
return description ? `await test.step(\`${description}\`, async () => {
|
||||
${body}
|
||||
});` : body;
|
||||
}
|
||||
function quoteMultiline(text, indent = ' ') {
|
||||
const escape = text => text.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/\$\{/g, '\\${');
|
||||
const lines = text.split('\n');
|
||||
if (lines.length === 1) return '`' + escape(text) + '`';
|
||||
return '`\n' + lines.map(line => indent + escape(line).replace(/\${/g, '\\${')).join('\n') + `\n${indent}\``;
|
||||
}
|
||||
function isMultilineString(text) {
|
||||
var _text$match;
|
||||
return (_text$match = text.match(/`[\S\s]*`/)) === null || _text$match === void 0 ? void 0 : _text$match[0].includes('\n');
|
||||
}
|
||||
47
node_modules/playwright-core/lib/server/codegen/jsonl.js
generated
vendored
Normal file
47
node_modules/playwright-core/lib/server/codegen/jsonl.js
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.JsonlLanguageGenerator = void 0;
|
||||
var _utils = require("../../utils");
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
class JsonlLanguageGenerator {
|
||||
constructor() {
|
||||
this.id = 'jsonl';
|
||||
this.groupName = '';
|
||||
this.name = 'JSONL';
|
||||
this.highlighter = 'javascript';
|
||||
}
|
||||
generateAction(actionInContext) {
|
||||
const locator = actionInContext.action.selector ? JSON.parse((0, _utils.asLocator)('jsonl', actionInContext.action.selector)) : undefined;
|
||||
const entry = {
|
||||
...actionInContext.action,
|
||||
pageAlias: actionInContext.frame.pageAlias,
|
||||
locator
|
||||
};
|
||||
return JSON.stringify(entry);
|
||||
}
|
||||
generateHeader(options) {
|
||||
return JSON.stringify(options);
|
||||
}
|
||||
generateFooter(saveStorage) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
exports.JsonlLanguageGenerator = JsonlLanguageGenerator;
|
||||
88
node_modules/playwright-core/lib/server/codegen/language.js
generated
vendored
Normal file
88
node_modules/playwright-core/lib/server/codegen/language.js
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.fromKeyboardModifiers = fromKeyboardModifiers;
|
||||
exports.generateCode = generateCode;
|
||||
exports.sanitizeDeviceOptions = sanitizeDeviceOptions;
|
||||
exports.toClickOptionsForSourceCode = toClickOptionsForSourceCode;
|
||||
exports.toKeyboardModifiers = toKeyboardModifiers;
|
||||
exports.toSignalMap = toSignalMap;
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
function generateCode(actions, languageGenerator, options) {
|
||||
const header = languageGenerator.generateHeader(options);
|
||||
const footer = languageGenerator.generateFooter(options.saveStorage);
|
||||
const actionTexts = actions.map(a => languageGenerator.generateAction(a)).filter(Boolean);
|
||||
const text = [header, ...actionTexts, footer].join('\n');
|
||||
return {
|
||||
header,
|
||||
footer,
|
||||
actionTexts,
|
||||
text
|
||||
};
|
||||
}
|
||||
function sanitizeDeviceOptions(device, options) {
|
||||
// Filter out all the properties from the device descriptor.
|
||||
const cleanedOptions = {};
|
||||
for (const property in options) {
|
||||
if (JSON.stringify(device[property]) !== JSON.stringify(options[property])) cleanedOptions[property] = options[property];
|
||||
}
|
||||
return cleanedOptions;
|
||||
}
|
||||
function toSignalMap(action) {
|
||||
let popup;
|
||||
let download;
|
||||
let dialog;
|
||||
for (const signal of action.signals) {
|
||||
if (signal.name === 'popup') popup = signal;else if (signal.name === 'download') download = signal;else if (signal.name === 'dialog') dialog = signal;
|
||||
}
|
||||
return {
|
||||
popup,
|
||||
download,
|
||||
dialog
|
||||
};
|
||||
}
|
||||
function toKeyboardModifiers(modifiers) {
|
||||
const result = [];
|
||||
if (modifiers & 1) result.push('Alt');
|
||||
if (modifiers & 2) result.push('ControlOrMeta');
|
||||
if (modifiers & 4) result.push('ControlOrMeta');
|
||||
if (modifiers & 8) result.push('Shift');
|
||||
return result;
|
||||
}
|
||||
function fromKeyboardModifiers(modifiers) {
|
||||
let result = 0;
|
||||
if (!modifiers) return result;
|
||||
if (modifiers.includes('Alt')) result |= 1;
|
||||
if (modifiers.includes('Control')) result |= 2;
|
||||
if (modifiers.includes('ControlOrMeta')) result |= 2;
|
||||
if (modifiers.includes('Meta')) result |= 4;
|
||||
if (modifiers.includes('Shift')) result |= 8;
|
||||
return result;
|
||||
}
|
||||
function toClickOptionsForSourceCode(action) {
|
||||
const modifiers = toKeyboardModifiers(action.modifiers);
|
||||
const options = {};
|
||||
if (action.button !== 'left') options.button = action.button;
|
||||
if (modifiers.length) options.modifiers = modifiers;
|
||||
// Do not render clickCount === 2 for dblclick.
|
||||
if (action.clickCount > 2) options.clickCount = action.clickCount;
|
||||
if (action.position) options.position = action.position;
|
||||
return options;
|
||||
}
|
||||
30
node_modules/playwright-core/lib/server/codegen/languages.js
generated
vendored
Normal file
30
node_modules/playwright-core/lib/server/codegen/languages.js
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.languageSet = languageSet;
|
||||
var _java = require("./java");
|
||||
var _javascript = require("./javascript");
|
||||
var _jsonl = require("./jsonl");
|
||||
var _csharp = require("./csharp");
|
||||
var _python = require("./python");
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
function languageSet() {
|
||||
return new Set([new _java.JavaLanguageGenerator('junit'), new _java.JavaLanguageGenerator('library'), new _javascript.JavaScriptLanguageGenerator( /* isPlaywrightTest */false), new _javascript.JavaScriptLanguageGenerator( /* isPlaywrightTest */true), new _python.PythonLanguageGenerator( /* isAsync */false, /* isPytest */true), new _python.PythonLanguageGenerator( /* isAsync */false, /* isPytest */false), new _python.PythonLanguageGenerator( /* isAsync */true, /* isPytest */false), new _csharp.CSharpLanguageGenerator('mstest'), new _csharp.CSharpLanguageGenerator('nunit'), new _csharp.CSharpLanguageGenerator('library'), new _jsonl.JsonlLanguageGenerator()]);
|
||||
}
|
||||
261
node_modules/playwright-core/lib/server/codegen/python.js
generated
vendored
Normal file
261
node_modules/playwright-core/lib/server/codegen/python.js
generated
vendored
Normal file
@@ -0,0 +1,261 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.PythonLanguageGenerator = void 0;
|
||||
var _language = require("./language");
|
||||
var _utils = require("../../utils");
|
||||
var _deviceDescriptors = require("../deviceDescriptors");
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
class PythonLanguageGenerator {
|
||||
constructor(isAsync, isPyTest) {
|
||||
this.id = void 0;
|
||||
this.groupName = 'Python';
|
||||
this.name = void 0;
|
||||
this.highlighter = 'python';
|
||||
this._awaitPrefix = void 0;
|
||||
this._asyncPrefix = void 0;
|
||||
this._isAsync = void 0;
|
||||
this._isPyTest = void 0;
|
||||
this.id = isPyTest ? 'python-pytest' : isAsync ? 'python-async' : 'python';
|
||||
this.name = isPyTest ? 'Pytest' : isAsync ? 'Library Async' : 'Library';
|
||||
this._isAsync = isAsync;
|
||||
this._isPyTest = isPyTest;
|
||||
this._awaitPrefix = isAsync ? 'await ' : '';
|
||||
this._asyncPrefix = isAsync ? 'async ' : '';
|
||||
}
|
||||
generateAction(actionInContext) {
|
||||
const action = actionInContext.action;
|
||||
if (this._isPyTest && (action.name === 'openPage' || action.name === 'closePage')) return '';
|
||||
const pageAlias = actionInContext.frame.pageAlias;
|
||||
const formatter = new PythonFormatter(4);
|
||||
if (action.name === 'openPage') {
|
||||
formatter.add(`${pageAlias} = ${this._awaitPrefix}context.new_page()`);
|
||||
if (action.url && action.url !== 'about:blank' && action.url !== 'chrome://newtab/') formatter.add(`${this._awaitPrefix}${pageAlias}.goto(${quote(action.url)})`);
|
||||
return formatter.format();
|
||||
}
|
||||
const locators = actionInContext.frame.framePath.map(selector => `.${this._asLocator(selector)}.content_frame`);
|
||||
const subject = `${pageAlias}${locators.join('')}`;
|
||||
const signals = (0, _language.toSignalMap)(action);
|
||||
if (signals.dialog) formatter.add(` ${pageAlias}.once("dialog", lambda dialog: dialog.dismiss())`);
|
||||
let code = `${this._awaitPrefix}${this._generateActionCall(subject, actionInContext)}`;
|
||||
if (signals.popup) {
|
||||
code = `${this._asyncPrefix}with ${pageAlias}.expect_popup() as ${signals.popup.popupAlias}_info {
|
||||
${code}
|
||||
}
|
||||
${signals.popup.popupAlias} = ${this._awaitPrefix}${signals.popup.popupAlias}_info.value`;
|
||||
}
|
||||
if (signals.download) {
|
||||
code = `${this._asyncPrefix}with ${pageAlias}.expect_download() as download${signals.download.downloadAlias}_info {
|
||||
${code}
|
||||
}
|
||||
download${signals.download.downloadAlias} = ${this._awaitPrefix}download${signals.download.downloadAlias}_info.value`;
|
||||
}
|
||||
formatter.add(code);
|
||||
return formatter.format();
|
||||
}
|
||||
_generateActionCall(subject, actionInContext) {
|
||||
const action = actionInContext.action;
|
||||
switch (action.name) {
|
||||
case 'openPage':
|
||||
throw Error('Not reached');
|
||||
case 'closePage':
|
||||
return `${subject}.close()`;
|
||||
case 'click':
|
||||
{
|
||||
let method = 'click';
|
||||
if (action.clickCount === 2) method = 'dblclick';
|
||||
const options = (0, _language.toClickOptionsForSourceCode)(action);
|
||||
const optionsString = formatOptions(options, false);
|
||||
return `${subject}.${this._asLocator(action.selector)}.${method}(${optionsString})`;
|
||||
}
|
||||
case 'check':
|
||||
return `${subject}.${this._asLocator(action.selector)}.check()`;
|
||||
case 'uncheck':
|
||||
return `${subject}.${this._asLocator(action.selector)}.uncheck()`;
|
||||
case 'fill':
|
||||
return `${subject}.${this._asLocator(action.selector)}.fill(${quote(action.text)})`;
|
||||
case 'setInputFiles':
|
||||
return `${subject}.${this._asLocator(action.selector)}.set_input_files(${formatValue(action.files.length === 1 ? action.files[0] : action.files)})`;
|
||||
case 'press':
|
||||
{
|
||||
const modifiers = (0, _language.toKeyboardModifiers)(action.modifiers);
|
||||
const shortcut = [...modifiers, action.key].join('+');
|
||||
return `${subject}.${this._asLocator(action.selector)}.press(${quote(shortcut)})`;
|
||||
}
|
||||
case 'navigate':
|
||||
return `${subject}.goto(${quote(action.url)})`;
|
||||
case 'select':
|
||||
return `${subject}.${this._asLocator(action.selector)}.select_option(${formatValue(action.options.length === 1 ? action.options[0] : action.options)})`;
|
||||
case 'assertText':
|
||||
return `expect(${subject}.${this._asLocator(action.selector)}).${action.substring ? 'to_contain_text' : 'to_have_text'}(${quote(action.text)})`;
|
||||
case 'assertChecked':
|
||||
return `expect(${subject}.${this._asLocator(action.selector)}).${action.checked ? 'to_be_checked()' : 'not_to_be_checked()'}`;
|
||||
case 'assertVisible':
|
||||
return `expect(${subject}.${this._asLocator(action.selector)}).to_be_visible()`;
|
||||
case 'assertValue':
|
||||
{
|
||||
const assertion = action.value ? `to_have_value(${quote(action.value)})` : `to_be_empty()`;
|
||||
return `expect(${subject}.${this._asLocator(action.selector)}).${assertion};`;
|
||||
}
|
||||
case 'assertSnapshot':
|
||||
return `expect(${subject}.${this._asLocator(action.selector)}).to_match_aria_snapshot(${quote(action.snapshot)})`;
|
||||
}
|
||||
}
|
||||
_asLocator(selector) {
|
||||
return (0, _utils.asLocator)('python', selector);
|
||||
}
|
||||
generateHeader(options) {
|
||||
const formatter = new PythonFormatter();
|
||||
if (this._isPyTest) {
|
||||
const contextOptions = formatContextOptions(options.contextOptions, options.deviceName, true /* asDict */);
|
||||
const fixture = contextOptions ? `
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def browser_context_args(browser_context_args, playwright) {
|
||||
return {${contextOptions}}
|
||||
}
|
||||
` : '';
|
||||
formatter.add(`${options.deviceName ? 'import pytest\n' : ''}import re
|
||||
from playwright.sync_api import Page, expect
|
||||
${fixture}
|
||||
|
||||
def test_example(page: Page) -> None {`);
|
||||
if (options.contextOptions.recordHar) formatter.add(` page.route_from_har(${quote(options.contextOptions.recordHar.path)})`);
|
||||
} else if (this._isAsync) {
|
||||
formatter.add(`
|
||||
import asyncio
|
||||
import re
|
||||
from playwright.async_api import Playwright, async_playwright, expect
|
||||
|
||||
|
||||
async def run(playwright: Playwright) -> None {
|
||||
browser = await playwright.${options.browserName}.launch(${formatOptions(options.launchOptions, false)})
|
||||
context = await browser.new_context(${formatContextOptions(options.contextOptions, options.deviceName)})`);
|
||||
if (options.contextOptions.recordHar) formatter.add(` await page.route_from_har(${quote(options.contextOptions.recordHar.path)})`);
|
||||
} else {
|
||||
formatter.add(`
|
||||
import re
|
||||
from playwright.sync_api import Playwright, sync_playwright, expect
|
||||
|
||||
|
||||
def run(playwright: Playwright) -> None {
|
||||
browser = playwright.${options.browserName}.launch(${formatOptions(options.launchOptions, false)})
|
||||
context = browser.new_context(${formatContextOptions(options.contextOptions, options.deviceName)})`);
|
||||
if (options.contextOptions.recordHar) formatter.add(` context.route_from_har(${quote(options.contextOptions.recordHar.path)})`);
|
||||
}
|
||||
return formatter.format();
|
||||
}
|
||||
generateFooter(saveStorage) {
|
||||
if (this._isPyTest) {
|
||||
return '';
|
||||
} else if (this._isAsync) {
|
||||
const storageStateLine = saveStorage ? `\n await context.storage_state(path=${quote(saveStorage)})` : '';
|
||||
return `\n # ---------------------${storageStateLine}
|
||||
await context.close()
|
||||
await browser.close()
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
async with async_playwright() as playwright:
|
||||
await run(playwright)
|
||||
|
||||
|
||||
asyncio.run(main())
|
||||
`;
|
||||
} else {
|
||||
const storageStateLine = saveStorage ? `\n context.storage_state(path=${quote(saveStorage)})` : '';
|
||||
return `\n # ---------------------${storageStateLine}
|
||||
context.close()
|
||||
browser.close()
|
||||
|
||||
|
||||
with sync_playwright() as playwright:
|
||||
run(playwright)
|
||||
`;
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.PythonLanguageGenerator = PythonLanguageGenerator;
|
||||
function formatValue(value) {
|
||||
if (value === false) return 'False';
|
||||
if (value === true) return 'True';
|
||||
if (value === undefined) return 'None';
|
||||
if (Array.isArray(value)) return `[${value.map(formatValue).join(', ')}]`;
|
||||
if (typeof value === 'string') return quote(value);
|
||||
if (typeof value === 'object') return JSON.stringify(value);
|
||||
return String(value);
|
||||
}
|
||||
function formatOptions(value, hasArguments, asDict) {
|
||||
const keys = Object.keys(value).filter(key => value[key] !== undefined).sort();
|
||||
if (!keys.length) return '';
|
||||
return (hasArguments ? ', ' : '') + keys.map(key => {
|
||||
if (asDict) return `"${(0, _utils.toSnakeCase)(key)}": ${formatValue(value[key])}`;
|
||||
return `${(0, _utils.toSnakeCase)(key)}=${formatValue(value[key])}`;
|
||||
}).join(', ');
|
||||
}
|
||||
function formatContextOptions(options, deviceName, asDict) {
|
||||
// recordHAR is replaced with routeFromHAR in the generated code.
|
||||
options = {
|
||||
...options,
|
||||
recordHar: undefined
|
||||
};
|
||||
const device = deviceName && _deviceDescriptors.deviceDescriptors[deviceName];
|
||||
if (!device) return formatOptions(options, false, asDict);
|
||||
return `**playwright.devices[${quote(deviceName)}]` + formatOptions((0, _language.sanitizeDeviceOptions)(device, options), true, asDict);
|
||||
}
|
||||
class PythonFormatter {
|
||||
constructor(offset = 0) {
|
||||
this._baseIndent = void 0;
|
||||
this._baseOffset = void 0;
|
||||
this._lines = [];
|
||||
this._baseIndent = ' '.repeat(4);
|
||||
this._baseOffset = ' '.repeat(offset);
|
||||
}
|
||||
prepend(text) {
|
||||
this._lines = text.trim().split('\n').map(line => line.trim()).concat(this._lines);
|
||||
}
|
||||
add(text) {
|
||||
this._lines.push(...text.trim().split('\n').map(line => line.trim()));
|
||||
}
|
||||
newLine() {
|
||||
this._lines.push('');
|
||||
}
|
||||
format() {
|
||||
let spaces = '';
|
||||
const lines = [];
|
||||
this._lines.forEach(line => {
|
||||
if (line === '') return lines.push(line);
|
||||
if (line === '}') {
|
||||
spaces = spaces.substring(this._baseIndent.length);
|
||||
return;
|
||||
}
|
||||
line = spaces + line;
|
||||
if (line.endsWith('{')) {
|
||||
spaces += this._baseIndent;
|
||||
line = line.substring(0, line.length - 1).trimEnd() + ':';
|
||||
}
|
||||
return lines.push(this._baseOffset + line);
|
||||
});
|
||||
return lines.join('\n');
|
||||
}
|
||||
}
|
||||
function quote(text) {
|
||||
return (0, _utils.escapeWithQuotes)(text, '\"');
|
||||
}
|
||||
5
node_modules/playwright-core/lib/server/codegen/types.js
generated
vendored
Normal file
5
node_modules/playwright-core/lib/server/codegen/types.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
Reference in New Issue
Block a user