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 },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!!
