Best JavaScript code snippet using playwright-internal
javascript.js
Source: javascript.js
1"use strict";2Object.defineProperty(exports, "__esModule", {3 value: true4});5exports.JavaScriptLanguageGenerator = exports.JavaScriptFormatter = void 0;6var _language = require("./language");7var _recorderActions = require("./recorderActions");8var _utils = require("./utils");9var _deviceDescriptors = _interopRequireDefault(require("../../deviceDescriptors"));10var _stringUtils = require("../../../utils/stringUtils");11function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }12/**13 * Copyright (c) Microsoft Corporation.14 *15 * Licensed under the Apache License, Version 2.0 (the "License");16 * you may not use this file except in compliance with the License.17 * You may obtain a copy of the License at18 *19 * http://www.apache.org/licenses/LICENSE-2.020 *21 * Unless required by applicable law or agreed to in writing, software22 * distributed under the License is distributed on an "AS IS" BASIS,23 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.24 * See the License for the specific language governing permissions and25 * limitations under the License.26 */27class JavaScriptLanguageGenerator {28 constructor(isTest) {29 this.id = void 0;30 this.fileName = void 0;31 this.highlighter = 'javascript';32 this._isTest = void 0;33 this.id = isTest ? 'test' : 'javascript';34 this.fileName = isTest ? 'Playwright Test' : 'JavaScript';35 this._isTest = isTest;36 }37 generateAction(actionInContext) {38 const {39 action,40 pageAlias41 } = actionInContext;42 const formatter = new JavaScriptFormatter(2);43 formatter.newLine();44 formatter.add('// ' + (0, _recorderActions.actionTitle)(action));45 if (action.name === 'openPage') {46 if (this._isTest) return '';47 formatter.add(`const ${pageAlias} = await context.newPage();`);48 if (action.url && action.url !== 'about:blank' && action.url !== 'chrome://newtab/') formatter.add(`await ${pageAlias}.goto(${quote(action.url)});`);49 return formatter.format();50 }51 const subject = actionInContext.isMainFrame ? pageAlias : actionInContext.frameName ? `${pageAlias}.frame(${formatObject({52 name: actionInContext.frameName53 })})` : `${pageAlias}.frame(${formatObject({54 url: actionInContext.frameUrl55 })})`;56 const signals = (0, _language.toSignalMap)(action);57 if (signals.dialog) {58 formatter.add(` ${pageAlias}.once('dialog', dialog => {59 console.log(\`Dialog message: $\{dialog.message()}\`);60 dialog.dismiss().catch(() => {});61 });`);62 }63 const emitPromiseAll = signals.waitForNavigation || signals.popup || signals.download;64 if (emitPromiseAll) {65 // Generate either await Promise.all([]) or66 // const [popup1] = await Promise.all([]).67 let leftHandSide = '';68 if (signals.popup) leftHandSide = `const [${signals.popup.popupAlias}] = `;else if (signals.download) leftHandSide = `const [download] = `;69 formatter.add(`${leftHandSide}await Promise.all([`);70 } // Popup signals.71 if (signals.popup) formatter.add(`${pageAlias}.waitForEvent('popup'),`); // Navigation signal.72 if (signals.waitForNavigation) formatter.add(`${pageAlias}.waitForNavigation(/*{ url: ${quote(signals.waitForNavigation.url)} }*/),`); // Download signals.73 if (signals.download) formatter.add(`${pageAlias}.waitForEvent('download'),`);74 const prefix = signals.popup || signals.waitForNavigation || signals.download ? '' : 'await ';75 const actionCall = this._generateActionCall(action);76 const suffix = signals.waitForNavigation || emitPromiseAll ? '' : ';';77 formatter.add(`${prefix}${subject}.${actionCall}${suffix}`);78 if (emitPromiseAll) {79 formatter.add(`]);`);80 } else if (signals.assertNavigation) {81 if (this._isTest) formatter.add(` await expect(${pageAlias}).toHaveURL(${quote(signals.assertNavigation.url)});`);else formatter.add(` // assert.equal(${pageAlias}.url(), ${quote(signals.assertNavigation.url)});`);82 }83 return formatter.format();84 }85 _generateActionCall(action) {86 switch (action.name) {87 case 'openPage':88 throw Error('Not reached');89 case 'closePage':90 return 'close()';91 case 'click':92 {93 let method = 'click';94 if (action.clickCount === 2) method = 'dblclick';95 const modifiers = (0, _utils.toModifiers)(action.modifiers);96 const options = {};97 if (action.button !== 'left') options.button = action.button;98 if (modifiers.length) options.modifiers = modifiers;99 if (action.clickCount > 2) options.clickCount = action.clickCount;100 if (action.position) options.position = action.position;101 const optionsString = formatOptions(options);102 return `${method}(${quote(action.selector)}${optionsString})`;103 }104 case 'check':105 return `check(${quote(action.selector)})`;106 case 'uncheck':107 return `uncheck(${quote(action.selector)})`;108 case 'fill':109 return `fill(${quote(action.selector)}, ${quote(action.text)})`;110 case 'setInputFiles':111 return `setInputFiles(${quote(action.selector)}, ${formatObject(action.files.length === 1 ? action.files[0] : action.files)})`;112 case 'press':113 {114 const modifiers = (0, _utils.toModifiers)(action.modifiers);115 const shortcut = [...modifiers, action.key].join('+');116 return `press(${quote(action.selector)}, ${quote(shortcut)})`;117 }118 case 'navigate':119 return `goto(${quote(action.url)})`;120 case 'select':121 return `selectOption(${quote(action.selector)}, ${formatObject(action.options.length > 1 ? action.options : action.options[0])})`;122 }123 }124 generateHeader(options) {125 if (this._isTest) return this.generateTestHeader(options);126 return this.generateStandaloneHeader(options);127 }128 generateFooter(saveStorage) {129 if (this._isTest) return this.generateTestFooter(saveStorage);130 return this.generateStandaloneFooter(saveStorage);131 }132 generateTestHeader(options) {133 const formatter = new JavaScriptFormatter();134 const useText = formatContextOptions(options.contextOptions, options.deviceName);135 formatter.add(`136 import { test, expect${options.deviceName ? ', devices' : ''} } from '@playwright/test';137${useText ? '\ntest.use(' + useText + ');\n' : ''}138 test('test', async ({ page }) => {`);139 return formatter.format();140 }141 generateTestFooter(saveStorage) {142 return `\n});`;143 }144 generateStandaloneHeader(options) {145 const formatter = new JavaScriptFormatter();146 formatter.add(`147 const { ${options.browserName}${options.deviceName ? ', devices' : ''} } = require('playwright');148 (async () => {149 const browser = await ${options.browserName}.launch(${formatObjectOrVoid(options.launchOptions)});150 const context = await browser.newContext(${formatContextOptions(options.contextOptions, options.deviceName)});`);151 return formatter.format();152 }153 generateStandaloneFooter(saveStorage) {154 const storageStateLine = saveStorage ? `\n await context.storageState({ path: ${quote(saveStorage)} });` : '';155 return `\n // ---------------------${storageStateLine}156 await context.close();157 await browser.close();158})();`;159 }160}161exports.JavaScriptLanguageGenerator = JavaScriptLanguageGenerator;162function formatOptions(value) {163 const keys = Object.keys(value);164 if (!keys.length) return '';165 return ', ' + formatObject(value);166}167function formatObject(value, indent = ' ') {168 if (typeof value === 'string') return quote(value);169 if (Array.isArray(value)) return `[${value.map(o => formatObject(o)).join(', ')}]`;170 if (typeof value === 'object') {171 const keys = Object.keys(value);172 if (!keys.length) return '{}';173 const tokens = [];174 for (const key of keys) tokens.push(`${key}: ${formatObject(value[key])}`);175 return `{\n${indent}${tokens.join(`,\n${indent}`)}\n}`;176 }177 return String(value);178}179function formatObjectOrVoid(value, indent = ' ') {180 const result = formatObject(value, indent);181 return result === '{}' ? '' : result;182}183function formatContextOptions(options, deviceName) {184 const device = deviceName && _deviceDescriptors.default[deviceName];185 if (!device) return formatObjectOrVoid(options); // Filter out all the properties from the device descriptor.186 let serializedObject = formatObjectOrVoid((0, _language.sanitizeDeviceOptions)(device, options)); // When there are no additional context options, we still want to spread the device inside.187 if (!serializedObject) serializedObject = '{\n}';188 const lines = serializedObject.split('\n');189 lines.splice(1, 0, `...devices[${quote(deviceName)}],`);190 return lines.join('\n');191}192class JavaScriptFormatter {193 constructor(offset = 0) {194 this._baseIndent = void 0;195 this._baseOffset = void 0;196 this._lines = [];197 this._baseIndent = ' '.repeat(2);198 this._baseOffset = ' '.repeat(offset);199 }200 prepend(text) {201 this._lines = text.trim().split('\n').map(line => line.trim()).concat(this._lines);202 }203 add(text) {204 this._lines.push(...text.trim().split('\n').map(line => line.trim()));205 }206 newLine() {207 this._lines.push('');208 }209 format() {210 let spaces = '';211 let previousLine = '';212 return this._lines.map(line => {213 if (line === '') return line;214 if (line.startsWith('}') || line.startsWith(']')) spaces = spaces.substring(this._baseIndent.length);215 const extraSpaces = /^(for|while|if|try).*\(.*\)$/.test(previousLine) ? this._baseIndent : '';216 previousLine = line;217 const callCarryOver = line.startsWith('.set');218 line = spaces + extraSpaces + (callCarryOver ? this._baseIndent : '') + line;219 if (line.endsWith('{') || line.endsWith('[')) spaces += this._baseIndent;220 return this._baseOffset + line;221 }).join('\n');222 }223}224exports.JavaScriptFormatter = JavaScriptFormatter;225function quote(text) {226 return (0, _stringUtils.escapeWithQuotes)(text, '\'');...
csharp.js
Source: csharp.js
1"use strict";2Object.defineProperty(exports, "__esModule", {3 value: true4});5exports.CSharpLanguageGenerator = void 0;6var _language = require("./language");7var _recorderActions = require("./recorderActions");8var _utils = require("./utils");9var _stringUtils = require("../../../utils/stringUtils");10var _deviceDescriptors = _interopRequireDefault(require("../../deviceDescriptors"));11function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }12/**13 * Copyright (c) Microsoft Corporation.14 *15 * Licensed under the Apache License, Version 2.0 (the "License");16 * you may not use this file except in compliance with the License.17 * You may obtain a copy of the License at18 *19 * http://www.apache.org/licenses/LICENSE-2.020 *21 * Unless required by applicable law or agreed to in writing, software22 * distributed under the License is distributed on an "AS IS" BASIS,23 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.24 * See the License for the specific language governing permissions and25 * limitations under the License.26 */27class CSharpLanguageGenerator {28 constructor() {29 this.id = 'csharp';30 this.fileName = 'C#';31 this.highlighter = 'csharp';32 }33 generateAction(actionInContext) {34 const {35 action,36 pageAlias37 } = actionInContext;38 const formatter = new CSharpFormatter(8);39 formatter.newLine();40 formatter.add('// ' + (0, _recorderActions.actionTitle)(action));41 if (action.name === 'openPage') {42 formatter.add(`var ${pageAlias} = await context.NewPageAsync();`);43 if (action.url && action.url !== 'about:blank' && action.url !== 'chrome://newtab/') formatter.add(`await ${pageAlias}.GotoAsync(${quote(action.url)});`);44 return formatter.format();45 }46 const subject = actionInContext.isMainFrame ? pageAlias : actionInContext.frameName ? `${pageAlias}.Frame(${quote(actionInContext.frameName)})` : `${pageAlias}.FrameByUrl(${quote(actionInContext.frameUrl)})`;47 const signals = (0, _language.toSignalMap)(action);48 if (signals.dialog) {49 formatter.add(` void ${pageAlias}_Dialog${signals.dialog.dialogAlias}_EventHandler(object sender, IDialog dialog)50 {51 Console.WriteLine($"Dialog message: {dialog.Message}");52 dialog.DismissAsync();53 ${pageAlias}.Dialog -= ${pageAlias}_Dialog${signals.dialog.dialogAlias}_EventHandler;54 }55 ${pageAlias}.Dialog += ${pageAlias}_Dialog${signals.dialog.dialogAlias}_EventHandler;`);56 }57 const lines = [];58 const actionCall = this._generateActionCall(action, actionInContext.isMainFrame);59 if (signals.waitForNavigation) {60 lines.push(`await ${pageAlias}.RunAndWaitForNavigationAsync(async () =>`);61 lines.push(`{`);62 lines.push(` await ${subject}.${actionCall};`);63 lines.push(`}/*, new ${actionInContext.isMainFrame ? 'Page' : 'Frame'}WaitForNavigationOptions`);64 lines.push(`{`);65 lines.push(` UrlString = ${quote(signals.waitForNavigation.url)}`);66 lines.push(`}*/);`);67 } else {68 lines.push(`await ${subject}.${actionCall};`);69 }70 if (signals.download) {71 lines.unshift(`var download${signals.download.downloadAlias} = await ${pageAlias}.RunAndWaitForDownloadAsync(async () =>\n{`);72 lines.push(`});`);73 }74 if (signals.popup) {75 lines.unshift(`var ${signals.popup.popupAlias} = await ${pageAlias}.RunAndWaitForPopupAsync(async () =>\n{`);76 lines.push(`});`);77 }78 for (const line of lines) formatter.add(line);79 if (signals.assertNavigation) formatter.add(` // Assert.AreEqual(${quote(signals.assertNavigation.url)}, ${pageAlias}.Url);`);80 return formatter.format();81 }82 _generateActionCall(action, isPage) {83 switch (action.name) {84 case 'openPage':85 throw Error('Not reached');86 case 'closePage':87 return 'CloseAsync()';88 case 'click':89 {90 let method = 'Click';91 if (action.clickCount === 2) method = 'DblClick';92 const modifiers = (0, _utils.toModifiers)(action.modifiers);93 const options = {};94 if (action.button !== 'left') options.button = action.button;95 if (modifiers.length) options.modifiers = modifiers;96 if (action.clickCount > 2) options.clickCount = action.clickCount;97 if (action.position) options.position = action.position;98 if (!Object.entries(options).length) return `${method}Async(${quote(action.selector)})`;99 const optionsString = formatObject(options, ' ', (isPage ? 'Page' : 'Frame') + method + 'Options');100 return `${method}Async(${quote(action.selector)}, ${optionsString})`;101 }102 case 'check':103 return `CheckAsync(${quote(action.selector)})`;104 case 'uncheck':105 return `UncheckAsync(${quote(action.selector)})`;106 case 'fill':107 return `FillAsync(${quote(action.selector)}, ${quote(action.text)})`;108 case 'setInputFiles':109 return `SetInputFilesAsync(${quote(action.selector)}, ${formatObject(action.files)})`;110 case 'press':111 {112 const modifiers = (0, _utils.toModifiers)(action.modifiers);113 const shortcut = [...modifiers, action.key].join('+');114 return `PressAsync(${quote(action.selector)}, ${quote(shortcut)})`;115 }116 case 'navigate':117 return `GotoAsync(${quote(action.url)})`;118 case 'select':119 return `SelectOptionAsync(${quote(action.selector)}, ${formatObject(action.options)})`;120 }121 }122 generateHeader(options) {123 const formatter = new CSharpFormatter(0);124 formatter.add(`125 using Microsoft.Playwright;126 using System;127 using System.Threading.Tasks;128 class Program129 {130 public static async Task Main()131 {132 using var playwright = await Playwright.CreateAsync();133 await using var browser = await playwright.${toPascal(options.browserName)}.LaunchAsync(${formatObject(options.launchOptions, ' ', 'BrowserTypeLaunchOptions')});134 var context = await browser.NewContextAsync(${formatContextOptions(options.contextOptions, options.deviceName)});`);135 return formatter.format();136 }137 generateFooter(saveStorage) {138 const storageStateLine = saveStorage ? `\n await context.StorageStateAsync(new BrowserContextStorageStateOptions\n {\n Path = ${quote(saveStorage)}\n });\n` : '';139 return `${storageStateLine} }140}\n`;141 }142}143exports.CSharpLanguageGenerator = CSharpLanguageGenerator;144function formatObject(value, indent = ' ', name = '') {145 if (typeof value === 'string') {146 if (['permissions', 'colorScheme', 'modifiers', 'button'].includes(name)) return `${getClassName(name)}.${toPascal(value)}`;147 return quote(value);148 }149 if (Array.isArray(value)) return `new[] { ${value.map(o => formatObject(o, indent, name)).join(', ')} }`;150 if (typeof value === 'object') {151 const keys = Object.keys(value);152 if (!keys.length) return name ? `new ${getClassName(name)}` : '';153 const tokens = [];154 for (const key of keys) {155 const property = getPropertyName(key);156 tokens.push(`${property} = ${formatObject(value[key], indent, key)},`);157 }158 if (name) return `new ${getClassName(name)}\n{\n${indent}${tokens.join(`\n${indent}`)}\n${indent}}`;159 return `{\n${indent}${tokens.join(`\n${indent}`)}\n${indent}}`;160 }161 if (name === 'latitude' || name === 'longitude') return String(value) + 'm';162 return String(value);163}164function getClassName(value) {165 switch (value) {166 case 'viewport':167 return 'ViewportSize';168 case 'proxy':169 return 'ProxySettings';170 case 'permissions':171 return 'ContextPermission';172 case 'modifiers':173 return 'KeyboardModifier';174 case 'button':175 return 'MouseButton';176 default:177 return toPascal(value);178 }179}180function getPropertyName(key) {181 switch (key) {182 case 'storageState':183 return 'StorageStatePath';184 case 'viewport':185 return 'ViewportSize';186 default:187 return toPascal(key);188 }189}190function toPascal(value) {191 return value[0].toUpperCase() + value.slice(1);192}193function formatContextOptions(options, deviceName) {194 const device = deviceName && _deviceDescriptors.default[deviceName];195 if (!device) {196 if (!Object.entries(options).length) return '';197 return formatObject(options, ' ', 'BrowserNewContextOptions');198 }199 options = (0, _language.sanitizeDeviceOptions)(device, options);200 if (!Object.entries(options).length) return `playwright.Devices[${quote(deviceName)}]`;201 return formatObject(options, ' ', `BrowserNewContextOptions(playwright.Devices[${quote(deviceName)}])`);202}203class CSharpFormatter {204 constructor(offset = 0) {205 this._baseIndent = void 0;206 this._baseOffset = void 0;207 this._lines = [];208 this._baseIndent = ' '.repeat(4);209 this._baseOffset = ' '.repeat(offset);210 }211 prepend(text) {212 this._lines = text.trim().split('\n').map(line => line.trim()).concat(this._lines);213 }214 add(text) {215 this._lines.push(...text.trim().split('\n').map(line => line.trim()));216 }217 newLine() {218 this._lines.push('');219 }220 format() {221 let spaces = '';222 let previousLine = '';223 return this._lines.map(line => {224 if (line === '') return line;225 if (line.startsWith('}') || line.startsWith(']') || line.includes('});') || line === ');') spaces = spaces.substring(this._baseIndent.length);226 const extraSpaces = /^(for|while|if).*\(.*\)$/.test(previousLine) ? this._baseIndent : '';227 previousLine = line;228 line = spaces + extraSpaces + line;229 if (line.endsWith('{') || line.endsWith('[') || line.endsWith('(')) spaces += this._baseIndent;230 if (line.endsWith('));')) spaces = spaces.substring(this._baseIndent.length);231 return this._baseOffset + line;232 }).join('\n');233 }234}235function quote(text) {236 return (0, _stringUtils.escapeWithQuotes)(text, '\"');...
python.js
Source: python.js
1"use strict";2Object.defineProperty(exports, "__esModule", {3 value: true4});5exports.PythonLanguageGenerator = void 0;6var _language = require("./language");7var _recorderActions = require("./recorderActions");8var _utils = require("./utils");9var _stringUtils = require("../../../utils/stringUtils");10var _deviceDescriptors = _interopRequireDefault(require("../../deviceDescriptors"));11function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }12/**13 * Copyright (c) Microsoft Corporation.14 *15 * Licensed under the Apache License, Version 2.0 (the "License");16 * you may not use this file except in compliance with the License.17 * You may obtain a copy of the License at18 *19 * http://www.apache.org/licenses/LICENSE-2.020 *21 * Unless required by applicable law or agreed to in writing, software22 * distributed under the License is distributed on an "AS IS" BASIS,23 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.24 * See the License for the specific language governing permissions and25 * limitations under the License.26 */27class PythonLanguageGenerator {28 constructor(isAsync) {29 this.id = 'python';30 this.fileName = 'Python';31 this.highlighter = 'python';32 this._awaitPrefix = void 0;33 this._asyncPrefix = void 0;34 this._isAsync = void 0;35 this.id = isAsync ? 'python-async' : 'python';36 this.fileName = isAsync ? 'Python Async' : 'Python';37 this._isAsync = isAsync;38 this._awaitPrefix = isAsync ? 'await ' : '';39 this._asyncPrefix = isAsync ? 'async ' : '';40 }41 generateAction(actionInContext) {42 const {43 action,44 pageAlias45 } = actionInContext;46 const formatter = new PythonFormatter(4);47 formatter.newLine();48 formatter.add('# ' + (0, _recorderActions.actionTitle)(action));49 if (action.name === 'openPage') {50 formatter.add(`${pageAlias} = ${this._awaitPrefix}context.new_page()`);51 if (action.url && action.url !== 'about:blank' && action.url !== 'chrome://newtab/') formatter.add(`${this._awaitPrefix}${pageAlias}.goto(${quote(action.url)})`);52 return formatter.format();53 }54 const subject = actionInContext.isMainFrame ? pageAlias : actionInContext.frameName ? `${pageAlias}.frame(${formatOptions({55 name: actionInContext.frameName56 }, false)})` : `${pageAlias}.frame(${formatOptions({57 url: actionInContext.frameUrl58 }, false)})`;59 const signals = (0, _language.toSignalMap)(action);60 if (signals.dialog) formatter.add(` ${pageAlias}.once("dialog", lambda dialog: dialog.dismiss())`);61 const actionCall = this._generateActionCall(action);62 let code = `${this._awaitPrefix}${subject}.${actionCall}`;63 if (signals.popup) {64 code = `${this._asyncPrefix}with ${pageAlias}.expect_popup() as popup_info {65 ${code}66 }67 ${signals.popup.popupAlias} = ${this._awaitPrefix}popup_info.value`;68 }69 if (signals.download) {70 code = `${this._asyncPrefix}with ${pageAlias}.expect_download() as download_info {71 ${code}72 }73 download = ${this._awaitPrefix}download_info.value`;74 }75 if (signals.waitForNavigation) {76 code = `77 # ${this._asyncPrefix}with ${pageAlias}.expect_navigation(url=${quote(signals.waitForNavigation.url)}):78 ${this._asyncPrefix}with ${pageAlias}.expect_navigation() {79 ${code}80 }`;81 }82 formatter.add(code);83 if (signals.assertNavigation) formatter.add(` # assert ${pageAlias}.url == ${quote(signals.assertNavigation.url)}`);84 return formatter.format();85 }86 _generateActionCall(action) {87 switch (action.name) {88 case 'openPage':89 throw Error('Not reached');90 case 'closePage':91 return 'close()';92 case 'click':93 {94 let method = 'click';95 if (action.clickCount === 2) method = 'dblclick';96 const modifiers = (0, _utils.toModifiers)(action.modifiers);97 const options = {};98 if (action.button !== 'left') options.button = action.button;99 if (modifiers.length) options.modifiers = modifiers;100 if (action.clickCount > 2) options.clickCount = action.clickCount;101 if (action.position) options.position = action.position;102 const optionsString = formatOptions(options, true);103 return `${method}(${quote(action.selector)}${optionsString})`;104 }105 case 'check':106 return `check(${quote(action.selector)})`;107 case 'uncheck':108 return `uncheck(${quote(action.selector)})`;109 case 'fill':110 return `fill(${quote(action.selector)}, ${quote(action.text)})`;111 case 'setInputFiles':112 return `set_input_files(${quote(action.selector)}, ${formatValue(action.files.length === 1 ? action.files[0] : action.files)})`;113 case 'press':114 {115 const modifiers = (0, _utils.toModifiers)(action.modifiers);116 const shortcut = [...modifiers, action.key].join('+');117 return `press(${quote(action.selector)}, ${quote(shortcut)})`;118 }119 case 'navigate':120 return `goto(${quote(action.url)})`;121 case 'select':122 return `select_option(${quote(action.selector)}, ${formatValue(action.options.length === 1 ? action.options[0] : action.options)})`;123 }124 }125 generateHeader(options) {126 const formatter = new PythonFormatter();127 if (this._isAsync) {128 formatter.add(`129import asyncio130from playwright.async_api import Playwright, async_playwright131async def run(playwright: Playwright) -> None {132 browser = await playwright.${options.browserName}.launch(${formatOptions(options.launchOptions, false)})133 context = await browser.new_context(${formatContextOptions(options.contextOptions, options.deviceName)})`);134 } else {135 formatter.add(`136from playwright.sync_api import Playwright, sync_playwright137def run(playwright: Playwright) -> None {138 browser = playwright.${options.browserName}.launch(${formatOptions(options.launchOptions, false)})139 context = browser.new_context(${formatContextOptions(options.contextOptions, options.deviceName)})`);140 }141 return formatter.format();142 }143 generateFooter(saveStorage) {144 if (this._isAsync) {145 const storageStateLine = saveStorage ? `\n await context.storage_state(path=${quote(saveStorage)})` : '';146 return `\n # ---------------------${storageStateLine}147 await context.close()148 await browser.close()149async def main() -> None:150 async with async_playwright() as playwright:151 await run(playwright)152asyncio.run(main())153`;154 } else {155 const storageStateLine = saveStorage ? `\n context.storage_state(path=${quote(saveStorage)})` : '';156 return `\n # ---------------------${storageStateLine}157 context.close()158 browser.close()159with sync_playwright() as playwright:160 run(playwright)161`;162 }163 }164}165exports.PythonLanguageGenerator = PythonLanguageGenerator;166function formatValue(value) {167 if (value === false) return 'False';168 if (value === true) return 'True';169 if (value === undefined) return 'None';170 if (Array.isArray(value)) return `[${value.map(formatValue).join(', ')}]`;171 if (typeof value === 'string') return quote(value);172 if (typeof value === 'object') return JSON.stringify(value);173 return String(value);174}175function toSnakeCase(name) {176 const toSnakeCaseRegex = /((?<=[a-z0-9])[A-Z]|(?!^)[A-Z](?=[a-z]))/g;177 return name.replace(toSnakeCaseRegex, `_$1`).toLowerCase();178}179function formatOptions(value, hasArguments) {180 const keys = Object.keys(value);181 if (!keys.length) return '';182 return (hasArguments ? ', ' : '') + keys.map(key => `${toSnakeCase(key)}=${formatValue(value[key])}`).join(', ');183}184function formatContextOptions(options, deviceName) {185 const device = deviceName && _deviceDescriptors.default[deviceName];186 if (!device) return formatOptions(options, false);187 return `**playwright.devices[${quote(deviceName)}]` + formatOptions((0, _language.sanitizeDeviceOptions)(device, options), true);188}189class PythonFormatter {190 constructor(offset = 0) {191 this._baseIndent = void 0;192 this._baseOffset = void 0;193 this._lines = [];194 this._baseIndent = ' '.repeat(4);195 this._baseOffset = ' '.repeat(offset);196 }197 prepend(text) {198 this._lines = text.trim().split('\n').map(line => line.trim()).concat(this._lines);199 }200 add(text) {201 this._lines.push(...text.trim().split('\n').map(line => line.trim()));202 }203 newLine() {204 this._lines.push('');205 }206 format() {207 let spaces = '';208 const lines = [];209 this._lines.forEach(line => {210 if (line === '') return lines.push(line);211 if (line === '}') {212 spaces = spaces.substring(this._baseIndent.length);213 return;214 }215 line = spaces + line;216 if (line.endsWith('{')) {217 spaces += this._baseIndent;218 line = line.substring(0, line.length - 1).trimEnd() + ':';219 }220 return lines.push(this._baseOffset + line);221 });222 return lines.join('\n');223 }224}225function quote(text) {226 return (0, _stringUtils.escapeWithQuotes)(text, '\"');...
language.js
Source: language.js
...18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.19 * See the License for the specific language governing permissions and20 * limitations under the License.21 */22function sanitizeDeviceOptions(device, options) {23 // Filter out all the properties from the device descriptor.24 const cleanedOptions = {};25 for (const property in options) {26 if (JSON.stringify(device[property]) !== JSON.stringify(options[property])) cleanedOptions[property] = options[property];27 }28 return cleanedOptions;29}30function toSignalMap(action) {31 let waitForNavigation;32 let assertNavigation;33 let popup;34 let download;35 let dialog;36 for (const signal of action.signals) {...
Using AI Code Generation
1const { sanitizeDeviceOptions } = require('playwright-core/lib/server/deviceDescriptors');2const { sanitizeDeviceOptions } = require('playwright-core/lib/server/deviceDescriptors');3const device = sanitizeDeviceOptions({4 userAgent: 'Mozilla/5.0 (Linux; Android 10; SM-G975F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.111 Mobile Safari/537.36',5 viewport: {6 },7});8const { chromium } = require('playwright');9(async () => {10 const browser = await chromium.launch();11 const context = await browser.newContext({12 });13 const page = await context.newPage();14 await browser.close();15})();16[MIT](./LICENSE)
Using AI Code Generation
1const { sanitizeDeviceOptions } = require('playwright/lib/server/deviceDescriptors');2const deviceOptions = {3 'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.2 Mobile/15E148 Safari/604.1',4 'viewport': {5 },6};7const sanitizedDeviceOptions = sanitizeDeviceOptions(deviceOptions);8console.log(sanitizedDeviceOptions);9The `sanitizeDeviceOptions` method is used to sanitize the device options, as per the [DeviceDescriptor](
Using AI Code Generation
1const { sanitizeDeviceOptions } = require('playwright-core/lib/server/deviceDescriptors');2const { devices } = require('playwright-core/lib/server/deviceDescriptors');3const { chromium } = require('playwright-core');4const iPhone11 = devices['iPhone 11 Pro'];5const iPhone11Modified = sanitizeDeviceOptions(iPhone11);6(async () => {7 const browser = await chromium.launch();8 const context = await browser.newContext({ ...iPhone11Modified, viewport: null });9 const page = await context.newPage();10 await page.screenshot({ path: 'iPhone11.png' });11 await browser.close();12})();13const { chromium } = require('playwright-core');14(async () => {15 const browser = await chromium.launch({16 });17})();18const { chromium } = require('playwright-core');19(async () => {20 const browser = await chromium.launch({21 });22})();23const { chromium } = require('playwright-core');24(async () => {25 const browser = await chromium.launch({26 proxy: {27 }28 });29})();30const { chromium } = require('playwright-core');31(async () => {
Using AI Code Generation
1const { sanitizeDeviceOptions } = require('playwright/lib/server/deviceDescriptors');2const deviceOptions = {3 userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1',4 viewport: {5 },6 userAgentMetadata: {7 }8};9const sanitizedDeviceOptions = sanitizeDeviceOptions(deviceOptions);10console.log(sanitizedDeviceOptions);
Using AI Code Generation
1const { sanitizeDeviceOptions } = require('playwright/lib/server/deviceDescriptors');2const device = sanitizeDeviceOptions({ name: 'iPhone 6', viewport: { width: 400, height: 400 } });3console.log(device);4{ name: 'iPhone 6',5 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.4 Mobile/15E148 Safari/604.1',6 viewport: { width: 375, height: 667, deviceScaleFactor: 2, isMobile: true, hasTouch: true, isLandscape: false },7 isLandscape: false }
Using AI Code Generation
1const { InternalUtils } = require('playwright/lib/server/utils');2const deviceOptions = {3 userAgent: 'Mozilla/5.0 (iPad; CPU OS 12_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148',4 viewport: { width: 1024, height: 768 },5 geolocation: { longitude: 12.492507, latitude: 41.889938 },6};7const sanitizedDeviceOptions = InternalUtils.sanitizeDeviceOptions(deviceOptions);8console.log(sanitizedDeviceOptions);9{10 userAgent: 'Mozilla/5.0 (iPad; CPU OS 12_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148',11 viewport: { width: 1024, height: 768 },12 geolocation: { longitude: 12.492507, latitude: 41.889938 },13}14const { InternalUtils } = require('playwright/lib/server/utils');15const deviceOptions = {16 userAgent: 'Mozilla/5.0 (iPad; CPU OS 12_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148',17 viewport: { width: 1024, height: 768 },18 geolocation: { longitude: 12.492507, latitude: 41.889938 },
Jest + Playwright - Test callbacks of event-based DOM library
firefox browser does not start in playwright
Is it possible to get the selector from a locator object in playwright?
How to run a list of test suites in a single file concurrently in jest?
Running Playwright in Azure Function
firefox browser does not start in playwright
This question is quite close to a "need more focus" question. But let's try to give it some focus:
Does Playwright has access to the cPicker object on the page? Does it has access to the window object?
Yes, you can access both cPicker and the window object inside an evaluate call.
Should I trigger the events from the HTML file itself, and in the callbacks, print in the DOM the result, in some dummy-element, and then infer from that dummy element text that the callbacks fired?
Exactly, or you can assign values to a javascript variable:
const cPicker = new ColorPicker({
onClickOutside(e){
},
onInput(color){
window['color'] = color;
},
onChange(color){
window['result'] = color;
}
})
And then
it('Should call all callbacks with correct arguments', async() => {
await page.goto(`http://localhost:5000/tests/visual/basic.html`, {waitUntil:'load'})
// Wait until the next frame
await page.evaluate(() => new Promise(requestAnimationFrame))
// Act
// Assert
const result = await page.evaluate(() => window['color']);
// Check the value
})
Check out the latest blogs from LambdaTest on this topic:
Native apps are developed specifically for one platform. Hence they are fast and deliver superior performance. They can be downloaded from various app stores and are not accessible through browsers.
One of the essential parts when performing automated UI testing, whether using Selenium or another framework, is identifying the correct web elements the tests will interact with. However, if the web elements are not located correctly, you might get NoSuchElementException in Selenium. This would cause a false negative result because we won’t get to the actual functionality check. Instead, our test will fail simply because it failed to interact with the correct element.
Smartphones have changed the way humans interact with technology. Be it travel, fitness, lifestyle, video games, or even services, it’s all just a few touches away (quite literally so). We only need to look at the growing throngs of smartphone or tablet users vs. desktop users to grasp this reality.
As part of one of my consulting efforts, I worked with a mid-sized company that was looking to move toward a more agile manner of developing software. As with any shift in work style, there is some bewilderment and, for some, considerable anxiety. People are being challenged to leave their comfort zones and embrace a continuously changing, dynamic working environment. And, dare I say it, testing may be the most ‘disturbed’ of the software roles in agile development.
LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!