First Commit

This commit is contained in:
2025-08-28 19:35:28 -07:00
commit 264e65006a
488 changed files with 155661 additions and 0 deletions

View File

@@ -0,0 +1,334 @@
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var csharp_exports = {};
__export(csharp_exports, {
CSharpLanguageGenerator: () => CSharpLanguageGenerator
});
module.exports = __toCommonJS(csharp_exports);
var import_language = require("./language");
var import_utils = require("../../utils");
var import_deviceDescriptors = require("../deviceDescriptors");
class CSharpLanguageGenerator {
constructor(mode) {
this.groupName = ".NET C#";
this.highlighter = "csharp";
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 "";
const pageAlias = this._formatPageAlias(actionInContext.frame.pageAlias);
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, import_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 () =>
{`);
lines.push(`});`);
}
if (signals.popup) {
lines.unshift(`var ${this._formatPageAlias(signals.popup.popupAlias)} = await ${pageAlias}.RunAndWaitForPopupAsync(async () =>
{`);
lines.push(`});`);
}
for (const line of lines)
formatter.add(line);
return formatter.format();
}
_formatPageAlias(pageAlias) {
if (this._mode === "library")
return pageAlias;
if (pageAlias === "page")
return "Page";
return pageAlias;
}
_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, import_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, import_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.ariaSnapshot)});`;
}
}
_asLocator(selector) {
return (0, import_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) {
const url = options.contextOptions.recordHar.urlFilter;
formatter.add(` await context.RouteFromHARAsync(${quote(options.contextOptions.recordHar.path)}${url ? `, ${formatObject({ url }, " ", "BrowserContextRouteFromHAROptions")}` : ""});`);
}
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) {
const url = options.contextOptions.recordHar.urlFilter;
formatter.add(` await Context.RouteFromHARAsync(${quote(options.contextOptions.recordHar.path)}${url ? `, ${formatObject({ url }, " ", "BrowserContextRouteFromHAROptions")}` : ""});`);
}
return formatter.format();
}
generateFooter(saveStorage) {
const offset = this._mode === "library" ? "" : " ";
let storageStateLine = saveStorage ? `
${offset}await context.StorageStateAsync(new BrowserContextStorageStateOptions
${offset}{
${offset} Path = ${quote(saveStorage)}
${offset}});
` : "";
if (this._mode !== "library")
storageStateLine += ` }
}
`;
return storageStateLine;
}
}
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] !== void 0).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)}
{
${indent}${tokens.join(`
${indent}`)}
${indent}}`;
return `{
${indent}${tokens.join(`
${indent}`)}
${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 };
delete options.recordHar;
const device = deviceName && import_deviceDescriptors.deviceDescriptors[deviceName];
if (!device) {
if (!Object.entries(options).length)
return "";
return formatObject(options, " ", "BrowserNewContextOptions");
}
options = (0, import_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._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, import_utils.escapeWithQuotes)(text, '"');
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
CSharpLanguageGenerator
});

270
node_modules/playwright-core/lib/server/codegen/java.js generated vendored Normal file
View File

@@ -0,0 +1,270 @@
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var java_exports = {};
__export(java_exports, {
JavaLanguageGenerator: () => JavaLanguageGenerator
});
module.exports = __toCommonJS(java_exports);
var import_language = require("./language");
var import_deviceDescriptors = require("../deviceDescriptors");
var import_javascript = require("./javascript");
var import_utils = require("../../utils");
class JavaLanguageGenerator {
constructor(mode) {
this.groupName = "Java";
this.highlighter = "java";
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 import_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, import_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, import_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, import_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.ariaSnapshot)});`;
}
}
_asLocator(selector, inFrameLocator) {
return (0, import_utils.asLocator)("java", selector, inFrameLocator);
}
generateHeader(options) {
const formatter = new import_javascript.JavaScriptFormatter();
if (this._mode === "junit") {
formatter.add(`
import com.microsoft.playwright.junit.UsePlaywright;
import com.microsoft.playwright.Page;
import com.microsoft.playwright.options.*;
${options.contextOptions.recordHar ? `import java.nio.file.Paths;
` : ""}import org.junit.jupiter.api.*;
import static com.microsoft.playwright.assertions.PlaywrightAssertions.*;
@UsePlaywright
public class TestExample {
@Test
void test(Page page) {`);
if (options.contextOptions.recordHar) {
const url = options.contextOptions.recordHar.urlFilter;
const recordHarOptions = typeof url === "string" ? `, new Page.RouteFromHAROptions()
.setUrl(${quote(url)})` : "";
formatter.add(` page.routeFromHAR(Paths.get(${quote(options.contextOptions.recordHar.path)})${recordHarOptions});`);
}
return formatter.format();
}
formatter.add(`
import com.microsoft.playwright.*;
import com.microsoft.playwright.options.*;
import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat;
${options.contextOptions.recordHar ? `import java.nio.file.Paths;
` : ""}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) {
const url = options.contextOptions.recordHar.urlFilter;
const recordHarOptions = typeof url === "string" ? `, new BrowserContext.RouteFromHAROptions()
.setUrl(${quote(url)})` : "";
formatter.add(` context.routeFromHAR(Paths.get(${quote(options.contextOptions.recordHar.path)})${recordHarOptions});`);
}
return formatter.format();
}
generateFooter(saveStorage) {
const storageStateLine = saveStorage ? `
context.storageState(new BrowserContext.StorageStateOptions().setPath(${quote(saveStorage)}));
` : "";
if (this._mode === "junit") {
return `${storageStateLine} }
}`;
}
return `${storageStateLine} }
}
}`;
}
}
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] !== void 0).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 ? import_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, import_utils.escapeWithQuotes)(text, '"');
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
JavaLanguageGenerator
});

View File

@@ -0,0 +1,268 @@
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var javascript_exports = {};
__export(javascript_exports, {
JavaScriptFormatter: () => JavaScriptFormatter,
JavaScriptLanguageGenerator: () => JavaScriptLanguageGenerator,
quoteMultiline: () => quoteMultiline
});
module.exports = __toCommonJS(javascript_exports);
var import_language = require("./language");
var import_utils = require("../../utils");
var import_deviceDescriptors = require("../deviceDescriptors");
class JavaScriptLanguageGenerator {
constructor(isTest) {
this.groupName = "Node.js";
this.highlighter = "javascript";
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, import_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, import_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, import_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": {
const commentIfNeeded = this._isTest ? "" : "// ";
return `${commentIfNeeded}await expect(${subject}.${this._asLocator(action.selector)}).toMatchAriaSnapshot(${quoteMultiline(action.ariaSnapshot, `${commentIfNeeded} `)});`;
}
}
}
_asLocator(selector) {
return (0, import_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) {
const url = options.contextOptions.recordHar.urlFilter;
formatter.add(` await page.routeFromHAR(${quote(options.contextOptions.recordHar.path)}${url ? `, ${formatOptions({ url }, false)}` : ""});`);
}
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 ? `
await context.storageState({ path: ${quote(saveStorage)} });` : "";
return `
// ---------------------${storageStateLine}
await context.close();
await browser.close();
})();`;
}
}
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] !== void 0).sort();
if (!keys.length)
return "{}";
const tokens = [];
for (const key of keys)
tokens.push(`${key}: ${formatObject(value[key])}`);
return `{
${indent}${tokens.join(`,
${indent}`)}
}`;
}
return String(value);
}
function formatObjectOrVoid(value, indent = " ") {
const result = formatObject(value, indent);
return result === "{}" ? "" : result;
}
function formatContextOptions(options, deviceName, isTest) {
const device = deviceName && import_deviceDescriptors.deviceDescriptors[deviceName];
options = { ...options, recordHar: void 0 };
if (!device)
return formatObjectOrVoid(options);
let serializedObject = formatObjectOrVoid((0, import_language.sanitizeDeviceOptions)(device, options));
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._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");
}
}
function quote(text) {
return (0, import_utils.escapeWithQuotes)(text, "'");
}
function wrapWithStep(description, body) {
return description ? `await test.step(\`${description}\`, async () => {
${body}
});` : body;
}
function quoteMultiline(text, indent = " ") {
const escape = (text2) => text2.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") + `
${indent}\``;
}
function isMultilineString(text) {
return text.match(/`[\S\s]*`/)?.[0].includes("\n");
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
JavaScriptFormatter,
JavaScriptLanguageGenerator,
quoteMultiline
});

View File

@@ -0,0 +1,52 @@
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var jsonl_exports = {};
__export(jsonl_exports, {
JsonlLanguageGenerator: () => JsonlLanguageGenerator
});
module.exports = __toCommonJS(jsonl_exports);
var import_utils = require("../../utils");
class JsonlLanguageGenerator {
constructor() {
this.id = "jsonl";
this.groupName = "";
this.name = "JSONL";
this.highlighter = "javascript";
}
generateAction(actionInContext) {
const locator = actionInContext.action.selector ? JSON.parse((0, import_utils.asLocator)("jsonl", actionInContext.action.selector)) : void 0;
const entry = {
...actionInContext.action,
...actionInContext.frame,
locator,
ariaSnapshot: void 0
};
return JSON.stringify(entry);
}
generateHeader(options) {
return JSON.stringify(options);
}
generateFooter(saveStorage) {
return "";
}
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
JsonlLanguageGenerator
});

View File

@@ -0,0 +1,132 @@
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var language_exports = {};
__export(language_exports, {
fromKeyboardModifiers: () => fromKeyboardModifiers,
generateCode: () => generateCode,
sanitizeDeviceOptions: () => sanitizeDeviceOptions,
toClickOptionsForSourceCode: () => toClickOptionsForSourceCode,
toKeyboardModifiers: () => toKeyboardModifiers,
toSignalMap: () => toSignalMap
});
module.exports = __toCommonJS(language_exports);
function generateCode(actions, languageGenerator, options) {
const header = languageGenerator.generateHeader(options);
const footer = languageGenerator.generateFooter(options.saveStorage);
const actionTexts = actions.map((a) => generateActionText(languageGenerator, a, !!options.generateAutoExpect)).filter(Boolean);
const text = [header, ...actionTexts, footer].join("\n");
return { header, footer, actionTexts, text };
}
function generateActionText(generator, action, generateAutoExpect) {
let text = generator.generateAction(action);
if (!text)
return;
if (generateAutoExpect && action.action.preconditionSelector) {
const expectAction = {
frame: action.frame,
startTime: action.startTime,
endTime: action.startTime,
action: {
name: "assertVisible",
selector: action.action.preconditionSelector,
signals: []
}
};
const expectText = generator.generateAction(expectAction);
if (expectText)
text = expectText + "\n\n" + text;
}
return text;
}
function sanitizeDeviceOptions(device, options) {
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;
if (action.clickCount > 2)
options.clickCount = action.clickCount;
if (action.position)
options.position = action.position;
return options;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
fromKeyboardModifiers,
generateCode,
sanitizeDeviceOptions,
toClickOptionsForSourceCode,
toKeyboardModifiers,
toSignalMap
});

View File

@@ -0,0 +1,68 @@
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var languages_exports = {};
__export(languages_exports, {
languageSet: () => languageSet
});
module.exports = __toCommonJS(languages_exports);
var import_csharp = require("./csharp");
var import_java = require("./java");
var import_javascript = require("./javascript");
var import_jsonl = require("./jsonl");
var import_python = require("./python");
function languageSet() {
return /* @__PURE__ */ new Set([
new import_javascript.JavaScriptLanguageGenerator(
/* isPlaywrightTest */
true
),
new import_javascript.JavaScriptLanguageGenerator(
/* isPlaywrightTest */
false
),
new import_python.PythonLanguageGenerator(
/* isAsync */
false,
/* isPytest */
true
),
new import_python.PythonLanguageGenerator(
/* isAsync */
false,
/* isPytest */
false
),
new import_python.PythonLanguageGenerator(
/* isAsync */
true,
/* isPytest */
false
),
new import_csharp.CSharpLanguageGenerator("mstest"),
new import_csharp.CSharpLanguageGenerator("nunit"),
new import_csharp.CSharpLanguageGenerator("library"),
new import_java.JavaLanguageGenerator("junit"),
new import_java.JavaLanguageGenerator("library"),
new import_jsonl.JsonlLanguageGenerator()
]);
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
languageSet
});

View File

@@ -0,0 +1,277 @@
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var python_exports = {};
__export(python_exports, {
PythonLanguageGenerator: () => PythonLanguageGenerator
});
module.exports = __toCommonJS(python_exports);
var import_language = require("./language");
var import_utils = require("../../utils");
var import_deviceDescriptors = require("../deviceDescriptors");
class PythonLanguageGenerator {
constructor(isAsync, isPyTest) {
this.groupName = "Python";
this.highlighter = "python";
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, import_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, import_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, import_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.ariaSnapshot)})`;
}
}
_asLocator(selector) {
return (0, import_utils.asLocator)("python", selector);
}
generateHeader(options) {
const formatter = new PythonFormatter();
const recordHar = options.contextOptions.recordHar;
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 || contextOptions ? "import pytest\n" : ""}import re
from playwright.sync_api import Page, expect
${fixture}
def test_example(page: Page) -> None {`);
if (recordHar)
formatter.add(` page.route_from_har(${quote(recordHar.path)}${typeof recordHar.urlFilter === "string" ? `, url=${quote(recordHar.urlFilter)}` : ""})`);
} 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 (recordHar)
formatter.add(` await context.route_from_har(${quote(recordHar.path)}${typeof recordHar.urlFilter === "string" ? `, url=${quote(recordHar.urlFilter)}` : ""})`);
} 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 (recordHar)
formatter.add(` context.route_from_har(${quote(recordHar.path)}${typeof recordHar.urlFilter === "string" ? `, url=${quote(recordHar.urlFilter)}` : ""})`);
}
return formatter.format();
}
generateFooter(saveStorage) {
if (this._isPyTest) {
return "";
} else if (this._isAsync) {
const storageStateLine = saveStorage ? `
await context.storage_state(path=${quote(saveStorage)})` : "";
return `
# ---------------------${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 ? `
context.storage_state(path=${quote(saveStorage)})` : "";
return `
# ---------------------${storageStateLine}
context.close()
browser.close()
with sync_playwright() as playwright:
run(playwright)
`;
}
}
}
function formatValue(value) {
if (value === false)
return "False";
if (value === true)
return "True";
if (value === void 0)
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] !== void 0).sort();
if (!keys.length)
return "";
return (hasArguments ? ", " : "") + keys.map((key) => {
if (asDict)
return `"${(0, import_utils.toSnakeCase)(key)}": ${formatValue(value[key])}`;
return `${(0, import_utils.toSnakeCase)(key)}=${formatValue(value[key])}`;
}).join(", ");
}
function formatContextOptions(options, deviceName, asDict) {
options = { ...options, recordHar: void 0 };
const device = deviceName && import_deviceDescriptors.deviceDescriptors[deviceName];
if (!device)
return formatOptions(options, false, asDict);
return `**playwright.devices[${quote(deviceName)}]` + formatOptions((0, import_language.sanitizeDeviceOptions)(device, options), true, asDict);
}
class PythonFormatter {
constructor(offset = 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, import_utils.escapeWithQuotes)(text, '"');
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
PythonLanguageGenerator
});

View File

@@ -0,0 +1,16 @@
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var types_exports = {};
module.exports = __toCommonJS(types_exports);