How to use pushTarget method in Playwright Internal

Best JavaScript code snippet using playwright-internal

config.js

Source:config.js Github

copy

Full Screen

1'use strict'2const path = require('path')3const inquirer = require('inquirer')4const minimist = require('minimist')5const { default: netrc } = require('netrc-parser')6const { rcFile } = require('rc-config-loader')7const { pretty, showVersion, usageExit, loadRequiedFile } = require('./util')8const loadKintoneCommands = async ({ commands, exclude }) => {9 const kintoneCommands = commands || loadRequiedFile(path.join(__dirname, 'commands'))10 if (exclude) {11 // TODO: -aオプションの複数指定もこの仕様に合わせた方が良いかも。。12 const excludeCommands = Array.isArray(exclude) ? exclude : [exclude]13 for (const excludeCommand of excludeCommands) {14 if (!kintoneCommands[excludeCommand]) {15 console.error(`ERROR: '${excludeCommand}' no such command!`)16 process.exit(1)17 }18 delete kintoneCommands[excludeCommand]19 }20 }21 return kintoneCommands22}23const loadGinuerc = async () => {24 const ginuercFile = rcFile('ginue')25 if (!ginuercFile) {26 return [{}]27 }28 const { config: ginuerc } = ginuercFile29 if (Array.isArray(ginuerc)) {30 console.error(`ERROR: The top-level structure of .ginuerc must not be array. (Since v2.0)`)31 process.exit(1)32 }33 if (!ginuerc.env) {34 return [ginuerc]35 }36 return Object.entries(ginuerc.env).map(([envName, envGinuerc]) => {37 envGinuerc.environment = envName38 // 内側のlocationはプロパティ名を変更しておく39 envGinuerc.envLocation = envGinuerc.location40 envGinuerc.location = ginuerc.location41 // location以外のプロパティは(外側 < 内側)の優先度で設定42 ;['fileType', 'preview', 'alt', 'commands', 'downloadJs', 'proxy'].forEach((prop) => {43 if (ginuerc[prop] && envGinuerc[prop] === undefined) {44 envGinuerc[prop] = ginuerc[prop]45 }46 })47 return envGinuerc48 })49}50const inputKintoneInfo = async (name, type = 'input') => {51 const value = await inquirer.prompt([52 {53 name,54 type,55 message: `Enter your kintone ${name}:`,56 validate: (value) => {57 if (value.length) {58 return true59 } else {60 return `Please enter your ${name}`61 }62 },63 },64 ])65 return value[name]66}67const stdInputOptions = async (opts) => {68 const TYPE_PASSWORD = 'password'69 // 標準入力しないオプションを画面表示(複数環境のアカウント情報入力などで間違えないため)70 for (const [optName, optValue] of Object.entries(opts)) {71 if (optValue) {72 // TODO: chalkなど使って色をつけたい73 let dispValue = pretty(optValue)74 switch (optName) {75 case 'password':76 case 'basic':77 dispValue = '[hidden]'78 break79 case 'pushTarget':80 continue81 }82 console.log(`${optName}: ${dispValue}`)83 }84 }85 if (opts.proxy instanceof Object) {86 const netrcProxyProps = netrc.machines[opts.proxy.hostname] || {}87 const netrcProxyAuth = `${netrcProxyProps.login}:${netrcProxyProps.password}`88 opts.proxy.auth = opts.proxy.auth || netrcProxyAuth89 }90 opts.domain = opts.domain || (await inputKintoneInfo('domain'))91 const netrcProps = netrc.machines[opts.domain] || {}92 const netrcBasic = netrcProps.account93 // TODO: コマンドライン引数のbasic処理と共通化したい94 if (!opts.basic && netrcBasic) {95 if (netrcBasic.includes(':')) {96 opts.basic = netrcBasic97 ;[opts.basic_user, opts.basic_password] = netrcBasic.split(':')98 } else if (!opts.basic_user) {99 opts.basic_user = netrcBasic100 }101 }102 if (opts.basic_user && !opts.basic_password) {103 // Basic認証のパスワードが省略された時だけ標準入力で問い合わせ104 // そもそもbasicオプションが指定されなかった場合は無視105 const basicPassword = await inputKintoneInfo('Basic Authentication password', TYPE_PASSWORD)106 opts.basic = `${opts.basic_user}:${basicPassword}`107 }108 opts.username =109 opts.username || netrcProps.login || process.env.GINUE_USERNAME || (await inputKintoneInfo('username'))110 opts.password =111 opts.password ||112 netrcProps.password ||113 process.env.GINUE_PASSWORD ||114 (await inputKintoneInfo('password', TYPE_PASSWORD))115 opts.basic = opts.basic || process.env.GINUE_BASIC116 // クライアント認証書のオプション117 opts.pfxFilepath = opts.pfxFilepath || process.env.GINUE_PFX_FILEPATH118 opts.pfxPassword =119 opts.pfxPassword ||120 process.env.GINUE_PFX_PASSWORD ||121 (opts.pfxFilepath && (await inputKintoneInfo('client certificate password', TYPE_PASSWORD)))122 opts.app = opts.app || (await inputKintoneInfo('app'))123 console.log()124 // TODO: 「is guest space?(Y/N)」のように問い合わせて、YならguestSpaceIdを入力125 // opts.guestSpaceId = opts.guestSpaceId || await inputKintoneInfo('guestSpaceID')126}127const parseArgumentOptions = () => {128 const argv = minimist(process.argv.slice(2), {129 // booleanを明記するとデフォルトfalseになってginuercとマージしづらいので書かない130 // 有効なオプションが分かるようにコメントとしては残しておく131 // boolean: ['version', 'help', 'preview', 'acl', 'alt'],132 string: [133 'location',134 'domain',135 'username',136 'password',137 'app',138 'guest',139 'basic',140 'exclude',141 'fileType',142 'appName',143 'pfxFilepath',144 'pfxPassword',145 ],146 alias: {147 v: 'version',148 h: 'help',149 l: 'location',150 d: 'domain',151 u: 'username',152 p: 'password',153 a: 'app',154 g: 'guest',155 b: 'basic',156 x: 'exclude',157 t: 'fileType',158 A: 'appName',159 F: 'pfxFilepath',160 P: 'pfxPassword',161 },162 })163 if (argv.domain || argv.username || argv.password || argv.app || argv.guest) {164 argv.priority = true165 }166 if (argv._[0]) {167 argv.type = argv._[0]168 }169 if (argv._[1]) {170 argv.target = argv._[1]171 }172 return argv173}174// TODO: minimistやめて、もっとリッチなライブラリを使う175// 引数や設定ファイルの組み合わせからオプション値を抽出176// firstObjを優先し、firstObjに存在しないプロパティはsecondObjを使用177const pluckOpts = (firstObj, secondObj) => {178 // TODO: previewやjsなどのboolean値はfirstObjがfalseでも必ず使われてしまうのを修正179 const obj = Object.assign({}, secondObj, firstObj)180 const opts = {181 location: obj.location,182 envLocation: obj.envLocation,183 environment: obj.environment,184 // TODO: プロキシ設定のドキュメント書く185 // ginuercに以下のいずれかで定義186 // proxy: {187 // protocol: 'https',188 // auth: 'username:password',189 // hostname: 'proxy.example.com',190 // port: 443,191 // },192 // proxy: 'https://username:password@proxy.example.com:443'193 // もしくは環境変数に書いてもOK(一般的な設定)194 // HTTPS_PROXY='https://username:password@proxy.example.com:443'195 proxy: obj.proxy,196 domain: obj.domain,197 username: obj.username,198 password: obj.password,199 app: obj.app,200 guestSpaceId: obj.guest,201 pushTarget: obj.pushTarget,202 // TODO: ginue diffコマンドを叩くとpreviewと運用環境との差分を表示したい(diffコマンドへのエイリアス?)203 preview: obj.preview,204 acl: obj.acl,205 field_acl: obj.field_acl,206 exclude: obj.exclude,207 fileType: obj.fileType,208 appName: obj.appName,209 alt: obj.alt,210 commands: obj.commands,211 downloadJs: obj.downloadJs,212 pfxFilepath: obj.pfxFilepath,213 pfxPassword: obj.pfxPassword,214 }215 // Basic認証のパスワード有無でプロパティ名を変えておく216 const basic = obj.basic217 if (basic) {218 if (basic.includes(':')) {219 opts.basic = basic220 } else {221 opts.basic_user = basic222 }223 }224 return opts225}226const createAppDic = (app) => {227 if (typeof app === 'string') {228 app = app.split(',').map((str) => str.trim())229 }230 if (Array.isArray(app)) {231 return app.reduce((obj, id) => {232 obj[id.toString()] = id233 return obj234 }, {})235 }236 return app237}238const createOptionValues = async () => {239 const argv = parseArgumentOptions()240 if (argv.version) {241 showVersion()242 }243 if (argv.help) {244 usageExit(0, argv.type)245 }246 if (!argv.type || !['pull', 'push', 'reset', 'deploy', 'erd'].includes(argv.type)) {247 usageExit(1)248 }249 const ginuerc = await loadGinuerc()250 let opts251 if (argv.target) {252 const [target, pushTarget] = argv.target.split(':')253 // push先target(コロンの右側)はginue pushの場合のみ指定可能254 if (pushTarget && argv.type !== 'push') {255 usageExit(1, argv.type)256 }257 const targetGinuercElem = ginuerc.find((g) => g.environment === target)258 if (!targetGinuercElem) {259 console.error(`ERROR: environment '${target}' not found.`)260 process.exit(1)261 }262 if (pushTarget) {263 // TODO: コマンドライン引数と組み合わさった場合の各種パターンを要テスト264 const pushTargetGinuercElem = ginuerc.find((g) => g.environment === pushTarget)265 if (!pushTargetGinuercElem) {266 console.error(`ERROR: environment '${pushTarget}' not found.`)267 process.exit(1)268 }269 if (Array.isArray(pushTargetGinuercElem.app) || Array.isArray(targetGinuercElem.app)) {270 console.error(`ERROR: 'app' should be Object if 'ginue push <env>:<env>' is specified.`)271 usageExit(1, 'push')272 }273 targetGinuercElem.pushTarget = pushTargetGinuercElem274 }275 opts = pluckOpts(argv, targetGinuercElem)276 } else if (ginuerc.length === 1) {277 // ginuercに単一環境だけ指定されている場合は、278 // argvを優先し、argvに存在しないオプションだけginuercを使う279 opts = pluckOpts(argv, ginuerc[0])280 } else if (argv.priority) {281 // ginuercに複数環境が指定され、argvにpriorityなオプションがある場合は、282 // ginuercを無視してargvのオプションだけ使う283 // argvには1種類の環境しか指定できず、ginuercの一部だけ使うことが難しいため284 opts = pluckOpts(argv)285 } else if (['push', 'reset', 'deploy'].includes(argv.type)) {286 // 送信系のコマンドは単一環境のみを対象にするため、ここまでの条件に合致しなければエラー287 // 複数環境への一括pushも技術的には難しくないけど、ヒューマンエラー防止のため非対応288 console.error('ERROR: <target environment> is required if .ginuerc has multiple environments.')289 usageExit(1, argv.type)290 } else {291 // 複数環境対応コマンドでargvにpriorityなオプションがなければ292 // ginuercの複数環境を全て使用293 // argvに何かしらオプションがあれば全環境でargvを優先294 opts = ginuerc.map((g) => pluckOpts(argv, g))295 }296 const allOpts = Array.isArray(opts) ? opts : [opts]297 // netrcに保存済みの情報取得298 netrc.loadSync()299 for (const opts of allOpts) {300 await stdInputOptions(opts)301 if (opts.pushTarget) {302 await stdInputOptions(opts.pushTarget)303 }304 opts.apps = createAppDic(opts.app)305 opts.type = argv.type306 }307 if (['push', 'reset', 'deploy'].includes(argv.type)) {308 const { isConfirmed } = await inquirer.prompt([309 {310 name: 'isConfirmed',311 type: 'confirm',312 message: `[${argv.type}] Are you sure?`,313 },314 ])315 if (!isConfirmed) {316 process.exit(0)317 }318 }319 return allOpts320}...

Full Screen

Full Screen

validate.js

Source:validate.js Github

copy

Full Screen

1const constant = require("./constant");2/**3 * @name pushTaskV3方法入参校验4 * @param {*} params5 */6const checkPushTaskV3 = (params) => {7 if (params) {8 // 校验source必填及值是否在枚举值里面9 if (!params.source) {10 return new Error("缺少source字段");11 } else if (constant.sourceMap.indexOf(params.source) === -1) {12 return new Error("source值不正确");13 }14 // 校验pushTarget15 if (!params.pushTarget) {16 return new Error("缺少推送目标(pushTarget)字段");17 } else if (18 Object.prototype.toString.call(params.pushTarget) !== "[Object Object]"19 ) {20 return new Error("推送目标(pushTarget)字段类型须为对象");21 } else {22 // 校验pushTarget下的target字段23 if (!params.pushTarget.target) {24 return new Error("推送目标(pushTarget)中缺少目标类型(target)字段");25 } else if (constant.targetMap.indexOf(params.pushTarget.target) === -1) {26 return new Error(27 "推送目标(pushTarget)中的目标类型(target)字段值不正确"28 );29 }30 // 校验pushTarget下的rids字段31 if (params.pushTarget.rids && !Array.isArray(params.pushTarget.rids)) {32 return new Error("推送目标(pushTarget)中的rids字段类型须为数组");33 }34 // 校验pushTarget下的tags字段35 if (params.pushTarget.tags && !Array.isArray(params.pushTarget.tags)) {36 return new Error("推送目标(pushTarget)中的tags字段类型须为数组");37 }38 // 校验pushTarget下的tagsType字段39 if (40 params.pushTarget.tagsType &&41 constant.tagsTypeMap.indexOf(params.pushTarget.tagsType) === -142 ) {43 return new Error("推送目标(pushTarget)中的tagsType字段值不正确");44 }45 // 校验pushTarget下的alias字段46 if (params.pushTarget.alias && !Array.isArray(params.pushTarget.alias)) {47 return new Error("推送目标(pushTarget)中的alias字段类型须为数组");48 }49 // 校验pushTarget下的smartLabels字段50 if (51 params.pushTarget.smartLabels &&52 !Array.isArray(params.pushTarget.smartLabels)53 ) {54 return new Error(55 "推送目标(pushTarget)中的smartLabels字段类型须为数组"56 );57 }58 // 校验pushTarget下的pushAreas字段59 if (60 params.pushTarget.pushAreas &&61 Object.prototype.toString.call(params.pushTarget.pushAreas) !==62 "[Object Object]"63 ) {64 return new Error("推送目标(pushTarget)中的pushAreas字段类型须为对象");65 }66 }67 // 校验pushNotify字段68 if (!params.pushNotify) {69 return new Error("缺少推送展示细节配置(pushNotify)字段");70 } else if (71 Object.prototype.toString.call(params.pushNotify) !== "[Object Object]"72 ) {73 return new Error("推送展示细节配置(pushNotify)字段类型须为对象");74 } else {75 // 校验pushNotify下的plats76 if (!params.pushNotify.plats) {77 return new Error("推送展示细节配置(pushNotify)中缺少plats字段");78 } else if (!Array.isArray(params.pushNotify.plats)) {79 ("推送展示细节配置(pushNotify)中plats字段类型须为数组");80 }81 // 校验pushNotify下的content82 if (!params.pushNotify.content) {83 return new Error(84 "推送展示细节配置(pushNotify)中缺少推送内容(content)字段"85 );86 }87 // 校验pushNotify下的type88 if (!params.pushNotify.type) {89 return new Error(90 "推送展示细节配置(pushNotify)中缺少推送类型(type)字段"91 );92 } else if (constant.pushTypeMap.indexOf(params.pushNotify.type) === -1) {93 return new Error(94 "推送展示细节配置(pushNotify)中的推送类型(type)字段值不正确"95 );96 }97 // 校验pushNotify下的customNotify98 if (99 params.pushNotify.customNotify &&100 Object.prototype.toString.call(params.pushNotify.customNotify) !==101 "[Object Object]"102 ) {103 return new Error(104 "推送展示细节配置(pushNotify)中的自定义内容(customNotify)字段类型须为对象"105 );106 }107 // 校验pushNotify下的androidNotify108 if (109 params.pushNotify.androidNotify &&110 Object.prototype.toString.call(params.pushNotify.androidNotify) !==111 "[Object Object]"112 ) {113 return new Error(114 "推送展示细节配置(pushNotify)中的androidNotify字段类型须为对象"115 );116 }117 // 校验pushNotify下的iosNotify118 if (119 params.pushNotify.iosNotify &&120 Object.prototype.toString.call(params.pushNotify.iosNotify) !==121 "[Object Object]"122 ) {123 return new Error(124 "推送展示细节配置(pushNotify)中的iosNotify字段类型须为对象"125 );126 }127 // 校验pushNotify下的extrasMapList128 if (129 params.pushNotify.extrasMapList &&130 !Array.isArray(params.pushNotify.extrasMapList)131 ) {132 return new Error(133 "推送展示细节配置(pushNotify)中的extrasMapList字段类型须为数组"134 );135 }136 }137 // 校验pushOperator字段138 if (139 params.pushOperator &&140 Object.prototype.toString.call(params.pushOperator) !== "[Object Object]"141 ) {142 return new Error("运营保障相关配置(pushOperator)字段类型须为对象");143 } else if (144 params.pushOperator &&145 Object.prototype.toString.call(params.pushOperator) === "[Object Object]"146 ) {147 // 校验pushOperator下的dropType字段148 if (149 params.pushOperator.dropType &&150 constant.dropTypeMap.indexOf(params.pushOperator.dropType) === -1151 ) {152 return new Error(153 "运营保障相关配置(pushOperator)中的修改类型(dropType)字段值不正确"154 );155 }156 }157 // 校验pushForward字段158 if (159 params.pushForward &&160 Object.prototype.toString.call(params.pushForward) !== "[Object Object]"161 ) {162 return new Error("pushForward字段类型须为对象");163 } else if (164 params.pushForward &&165 Object.prototype.toString.call(params.pushForward) === "[Object Object]"166 ) {167 // 校验pushForward下的nextType168 if (169 params.pushForward.nextType &&170 constant.nextTypeMap.indexOf(params.pushForward.nextType) === -1171 ) {172 return new Error("pushForward中的nextType字段值不正确");173 }174 // 校验pushForward下的url175 // if (!params.pushForward.url) {176 // return new Error("pushForward中缺少url字段");177 // }178 // 校验pushForward下的schemeDataList字段179 if (180 params.pushForward.schemeDataList &&181 !Array.isArray(params.pushForward.schemeDataList)182 ) {183 return new Error("pushForward中的schemeDataList字段类型须为数组");184 }185 }186 } else {187 return new Error("缺少入参");188 }189 return "入参校验通过";190};...

Full Screen

Full Screen

docker.js

Source:docker.js Github

copy

Full Screen

1var childProcess = require('child_process');2var pkg = require('../package.json');3var chalk = require('chalk');4/**5 * For ease of use add the following line to scripts in package.json: `"docker:build": "node scripts/docker.js"`6 *7 * **Usage:**8 *9 * * `yarn run docker:build`10 * > This will just build the image: `organization/package-name:0.1.0`11 *12 * * `yarn run docker:build -- --tag-suffix`13 * > This will just build the image with git ref suffix: `organization/package-name:0.1.0-90b0665`14 *15 * * `yarn run docker:build -- --push`16 * > This will build and push the image to Docker Hub: `organization/package-name:0.1.0`17 *18 * * `yarn run docker:build -- --push --tag-suffix`19 * > This will build and push the image to Docker Hub with git ref suffix: `organization/package-name:0.1.0-90b0665`20 *21 * * `yarn run docker:build -- --push --tag-suffix stage`22 * > This will build and push the image to Docker Hub with custom suffix: `organization/package-name:0.1.0-90b0665-stage`23 *24 * * `yarn run docker:build -- --push aws_account_id.dkr.ecr.eu-central-1.amazonaws.com --tag-suffix dev`25 * > This will build and push the image to AWS ECR with custom suffix: `aws_account_id.dkr.ecr.eu-central-1.amazonaws.com/package-name:0.1.0-90b0665-dev`26 *27 */28const buildDocker = async () => {29 return new Promise((resolve, reject) => {30 execChildProcess('git', 'rev-parse --short HEAD').then((ref) => {31 return ref.replace(/^(.*?)[\r\n]*$/, '$1'); // remove line breaks from output if present32 }).then((vcsRef) => {33 if (!process.env.GITHUB_TOKEN) {34 return reject(chalk.redBright('missing GITHUB_TOKEN environment variable!'));35 }36 var version = pkg.version || 'latest'; // fallback to 'latest' if no version is set in package.json37 var date = new Date().toISOString(); // get current date in ISO format38 var name = pkg.name.replace(/^(?:@\w*\/)?(.*)$/, '$1'); // remove organization prefix from package name if present39 var organization = pkg.name.replace(/^(?:@(\w*)\/)?.*$/, '$1') || 'nordeck'; // get organization from package name40 var getArgument = (name) => {41 var argIndex = process.argv.indexOf(name);42 if (argIndex > -1) {43 if (process.argv.length > argIndex + 1) {44 return process.argv[argIndex + 1];45 }46 return true;47 }48 }49 var pushTarget = getArgument('--push');50 if (pushTarget) {51 if (pushTarget === true) {52 pushTarget = organization;53 }54 console.log(chalk.blueBright(`image will be pushed to ${pushTarget}`))55 }56 var tag = `${pushTarget || organization}/${name}:${version}`57 var tagSuffix = getArgument('--tag-suffix');58 if (tagSuffix) {59 if (tagSuffix === true) {60 tag += `-${vcsRef}`;61 } else {62 tag += `-${vcsRef}-${tagSuffix}`63 }64 }65 var maxLabelLength = 100;66 var formatInfo = (label, value) => chalk.cyanBright('║') + ` ${`${label}:`.padEnd(12, ' ')} ${value}`.padEnd(maxLabelLength, ' ').substring(0, maxLabelLength) + chalk.cyanBright('║');67 console.log(chalk.cyanBright(`╔${'═'.repeat(maxLabelLength)}╗`))68 console.log(formatInfo('image', tag));69 console.log(formatInfo('git ref', vcsRef));70 console.log(formatInfo('build date', date));71 console.log(chalk.cyanBright(`╚${'═'.repeat(maxLabelLength)}╝`))72 var cmd = childProcess.spawn('docker', `build --build-arg CI --build-arg VCS_REF --build-arg VERSION --build-arg BUILD_DATE --build-arg GITHUB_TOKEN -t ${tag}${tagSuffix ? '' : ` -t ${`${pushTarget || organization}/${name}:latest`}`} .`.split(' '), {73 env: {74 CI: true,75 VCS_REF: vcsRef,76 VERSION: version,77 BUILD_DATE: date,78 GITHUB_TOKEN: process.env.GITHUB_TOKEN79 }80 });81 cmd.stdout.on('data', function (output) {82 var val = output.toString().replace(/^(.*?)[\r\n]*$/, '$1');83 console.log(val);84 });85 cmd.stderr.on('data', function (err) {86 var val = err.toString().replace(/^(.*?)[\r\n]*$/, '$1');87 console.error(chalk.redBright(val));88 });89 cmd.on('exit', code => {90 if (code === 0) {91 // output image name and tag to github action92 console.log(`::set-output name=image::${tag}`)93 console.log(`::set-output name=container::${name}`)94 if (pushTarget) {95 execChildProcess('docker', `push ${pushTarget || organization}/${name}`, false).then(() => {96 resolve(chalk.greenBright(`docker image build and pushed successfully (${tag})!`));97 }).catch((err) => {98 console.error(chalk.redBright(`unable to push docker image (${tag})!`));99 reject(err);100 });101 } else {102 resolve(chalk.greenBright('docker build completed successfully!'));103 }104 } else {105 reject(chalk.redBright('docker build failed!'));106 }107 });108 }).catch((err) => {109 console.error(chalk.redBright('unable to read git ref!'));110 reject(err);111 });112 });113}114const execChildProcess = (command, options, resolveOnOutput = true) => {115 return new Promise((resolve, reject) => {116 var cmd = childProcess.spawn(command, options.split(' '));117 cmd.stdout.on('data', function (output) {118 var val = output.toString().replace(/^(.*?)[\r\n]*$/, '$1');119 if (resolveOnOutput) {120 resolve(val);121 } else {122 console.log(val);123 }124 });125 cmd.stderr.on('data', function (err) {126 var val = err.toString().replace(/^(.*?)[\r\n]*$/, '$1');127 if (resolveOnOutput) {128 reject(val);129 } else {130 console.error(val);131 }132 });133 cmd.on('exit', code => {134 if (code === 0) {135 resolve('task completed successfully!');136 } else {137 reject('task failed!');138 }139 });140 });141}142buildDocker().then((message) => {143 console.log(message);144 process.exit(0);145}).catch((err) => {146 console.error(err);147 process.exit(1);...

Full Screen

Full Screen

tools.js

Source:tools.js Github

copy

Full Screen

1/**2 * @name pushTaskV3方法入参格式化3 * @param {*} params4 */5const composeObj = (params) => {6 return {7 workno: params.workno || "",8 source: params.source || "webapi",9 pushTarget: {10 target: params.pushTarget && params.pushTarget.target,11 tags: params.pushTarget && params.pushTarget.tags,12 tagsType: (params.pushTarget && params.pushTarget.tagsType) || 1,13 alias: params.pushTarget && params.pushTarget.alias,14 rids: params.pushTarget && params.pushTarget.rids,15 block: params.pushTarget && params.pushTarget.block,16 city: params.pushTarget && params.pushTarget.city,17 country: params.pushTarget && params.pushTarget.country,18 province: params.pushTarget && params.pushTarget.province,19 smartLabels: params.pushTarget && params.pushTarget.smartLabels,20 pushAreas: params.pushTarget && params.pushTarget.pushAreas,21 },22 pushNotify: {23 taskCron: (params.pushNotify && params.pushNotify.taskCron) || 0,24 taskTime: params.pushNotify && params.pushNotify.taskTime,25 plats: (params.pushNotify && params.pushNotify.plats) || [1, 2],26 iosProduction:27 (params.pushNotify && params.pushNotify.iosProduction) || 1,28 offlineSeconds:29 (params.pushNotify && params.pushNotify.offlineSeconds) || 0,30 content: params.pushNotify && params.pushNotify.content,31 title: params.pushNotify && params.pushNotify.title,32 type: (params.pushNotify && params.pushNotify.iosProduction) || 1,33 customNotify: params.pushNotify && params.pushNotify.customNotify,34 androidNotify: {35 appName:36 params.pushNotify &&37 params.pushNotify.androidNotify &&38 params.pushNotify.androidNotify.appName,39 title:40 params.pushNotify &&41 params.pushNotify.androidNotify &&42 params.pushNotify.androidNotify.title,43 warn:44 (params.pushNotify &&45 params.pushNotify.androidNotify &&46 params.pushNotify.androidNotify.warn) ||47 "12",48 style:49 (params.pushNotify &&50 params.pushNotify.androidNotify &&51 params.pushNotify.androidNotify.style) ||52 0,53 content:54 params.pushNotify &&55 params.pushNotify.androidNotify &&56 params.pushNotify.androidNotify.content,57 sound:58 params.pushNotify &&59 params.pushNotify.androidNotify &&60 params.pushNotify.androidNotify.sound,61 },62 iosNotify: {63 title:64 params.pushNotify &&65 params.pushNotify.iosNotify &&66 params.pushNotify.iosNotify.title,67 subtitle:68 params.pushNotify &&69 params.pushNotify.iosNotify &&70 params.pushNotify.iosNotify.subtitle,71 sound:72 (params.pushNotify &&73 params.pushNotify.iosNotify &&74 params.pushNotify.iosNotify.sound) ||75 "default",76 badge:77 params.pushNotify &&78 params.pushNotify.iosNotify &&79 params.pushNotify.iosNotify.badge,80 badgeType:81 params.pushNotify &&82 params.pushNotify.iosNotify &&83 params.pushNotify.iosNotify.badgeType,84 category:85 params.pushNotify &&86 params.pushNotify.iosNotify &&87 params.pushNotify.iosNotify.category,88 slientPush:89 params.pushNotify &&90 params.pushNotify.iosNotify &&91 params.pushNotify.iosNotify.slientPush,92 contentAvailable:93 params.pushNotify &&94 params.pushNotify.iosNotify &&95 params.pushNotify.iosNotify.contentAvailable,96 mutableContent:97 params.pushNotify &&98 params.pushNotify.iosNotify &&99 params.pushNotify.iosNotify.mutableContent,100 attachmentType:101 params.pushNotify &&102 params.pushNotify.iosNotify &&103 params.pushNotify.iosNotify.attachmentType,104 attachment:105 params.pushNotify &&106 params.pushNotify.iosNotify &&107 params.pushNotify.iosNotify.attachment,108 },109 url: params.pushNotify && params.pushNotify.url,110 extrasMapList: params.pushNotify && params.pushNotify.extrasMapList,111 },112 pushOperator: {113 dropType: params.pushOperator && params.pushOperator.dropType,114 dropId: params.pushOperator && params.pushOperator.dropId,115 notifyId: params.pushOperator && params.pushOperator.notifyId,116 },117 pushForward: {118 nextType: (params.pushForward && params.pushForward.nextType) || 0,119 url: params.pushForward && params.pushForward.url,120 scheme: params.pushForward && params.pushForward.scheme,121 schemeDataList: params.pushForward && params.pushForward.schemeDataList,122 },123 };124};125module.exports = {126 composeObj,...

Full Screen

Full Screen

index.js

Source:index.js Github

copy

Full Screen

1#!/usr/bin/env node2'use strict'3const { inspect } = require('util')4const { createBase64Account } = require('./lib/util')5const { createOptionValues, loadKintoneCommands } = require('./lib/config')6const { ginuePull } = require('./lib/pull')7const { ginuePush } = require('./lib/push')8const { ginueDeploy, ginueReset } = require('./lib/deploy')9const { ginueErd } = require('./lib/erd')10const main = async () => {11 const allOpts = await createOptionValues()12 // 環境単位ループ13 allOpts.forEach(async (opts) => {14 try {15 const base64Basic = await createBase64Account(opts.basic)16 const base64Account = await createBase64Account(opts.username, opts.password)17 if (['reset', 'deploy'].includes(opts.type)) {18 const ktn = {19 proxy: opts.proxy,20 domain: opts.domain,21 guestSpaceId: opts.guestSpaceId,22 base64Account,23 base64Basic,24 apps: opts.apps,25 pfxFilepath: opts.pfxFilepath,26 pfxPassword: opts.pfxPassword,27 }28 switch (opts.type) {29 case 'reset':30 await ginueReset(ktn, opts)31 break32 case 'deploy':33 await ginueDeploy(ktn, opts)34 break35 }36 return37 }38 if (opts.type === 'erd') {39 ginueErd(opts)40 return41 }42 const pushTargetKtn = opts.pushTarget && {43 domain: opts.pushTarget.domain,44 guestSpaceId: opts.pushTarget.guestSpaceId,45 base64Basic: await createBase64Account(opts.pushTarget.basic),46 base64Account: await createBase64Account(opts.pushTarget.username, opts.pushTarget.password),47 pfxFilepath: opts.pushTarget.pfxFilepath,48 pfxPassword: opts.pushTarget.pfxPassword,49 }50 // TODO: スペース単位ループを可能にする(スペース内全アプリをpull)51 // アプリ単位ループ52 for (const [appName, appId] of Object.entries(opts.apps)) {53 if (opts.appName && opts.appName !== appName) {54 continue55 }56 const environment = opts.pushTarget ? opts.pushTarget.environment : opts.environment57 const target = `----------${environment}/${appName}----------`58 console.log(target)59 const kintoneCommands = await loadKintoneCommands({ commands: opts.commands, exclude: opts.exclude })60 const requestPromises = []61 // APIコマンド単位ループ62 for (const [commName, commProp] of Object.entries(kintoneCommands)) {63 const preview = Boolean(commProp.hasPreview && opts.preview)64 const ktn = {65 proxy: opts.proxy,66 domain: opts.domain,67 guestSpaceId: opts.guestSpaceId,68 base64Account,69 base64Basic,70 appName,71 appId,72 command: commName,73 appParam: commProp.appParam,74 methods: commProp.methods,75 pfxFilepath: opts.pfxFilepath,76 pfxPassword: opts.pfxPassword,77 }78 switch (opts.type) {79 case 'pull':80 requestPromises.push(ginuePull({ ...ktn, preview }, opts))81 break82 case 'push':83 if (commName.includes('/acl.json') && !opts.acl) {84 console.log(`[SKIP] ${commName}`)85 break86 }87 if (commName === 'field/acl.json' && !opts.field_acl) {88 console.log(`[SKIP] ${commName}`)89 break90 }91 if (pushTargetKtn) {92 pushTargetKtn.appId = opts.pushTarget.app[ktn.appName]93 }94 await ginuePush(ktn, opts, pushTargetKtn)95 break96 }97 }98 await Promise.all(requestPromises)99 }100 } catch (error) {101 try {102 const message = JSON.parse(error.message)103 console.error(inspect(message, { depth: Infinity, colors: true }))104 delete error.message105 } catch (e) {106 } finally {107 console.error(error)108 }109 }110 })111}...

Full Screen

Full Screen

PushTarget.js

Source:PushTarget.js Github

copy

Full Screen

1/**2 * Callback and Related APIs3 * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)4 *5 * OpenAPI spec version: 3.0.000.19.0166 *7 * NOTE: This class is auto generated by the swagger code generator program.8 * https://github.com/swagger-api/swagger-codegen.git9 *10 * Swagger Codegen version: 2.4.511 *12 * Do not edit the class manually.13 *14 */15(function(root, factory) {16 if (typeof define === 'function' && define.amd) {17 // AMD. Register as an anonymous module.18 define(['ApiClient'], factory);19 } else if (typeof module === 'object' && module.exports) {20 // CommonJS-like environments that support module.exports, like Node.21 module.exports = factory(require('../ApiClient'));22 } else {23 // Browser globals (root is window)24 if (!root.CallbackAndRelatedApIs) {25 root.CallbackAndRelatedApIs = {};26 }27 root.CallbackAndRelatedApIs.PushTarget = factory(root.CallbackAndRelatedApIs.ApiClient);28 }29}(this, function(ApiClient) {30 'use strict';31 /**32 * The PushTarget model module.33 * @module model/PushTarget34 * @version 3.0.000.19.01635 */36 /**37 * Constructs a new <code>PushTarget</code>.38 * @alias module:model/PushTarget39 * @class40 * @param channel {String} Channel name. The only accepted value is 'FCM' for now.41 * @param target {String} Unique identifier of the recipient of the message. For FCM, this is the 'registration token'.42 */43 var exports = function(channel, target) {44 var _this = this;45 _this['channel'] = channel;46 _this['target'] = target;47 };48 /**49 * Constructs a <code>PushTarget</code> from a plain JavaScript object, optionally creating a new instance.50 * Copies all relevant properties from <code>data</code> to <code>obj</code> if supplied or a new instance if not.51 * @param {Object} data The plain JavaScript object bearing properties of interest.52 * @param {module:model/PushTarget} obj Optional instance to populate.53 * @return {module:model/PushTarget} The populated <code>PushTarget</code> instance.54 */55 exports.constructFromObject = function(data, obj) {56 if (data) {57 obj = obj || new exports();58 if (data.hasOwnProperty('channel')) {59 obj['channel'] = ApiClient.convertToType(data['channel'], 'String');60 }61 if (data.hasOwnProperty('target')) {62 obj['target'] = ApiClient.convertToType(data['target'], 'String');63 }64 }65 return obj;66 }67 /**68 * Channel name. The only accepted value is 'FCM' for now.69 * @member {String} channel70 */71 exports.prototype['channel'] = undefined;72 /**73 * Unique identifier of the recipient of the message. For FCM, this is the 'registration token'.74 * @member {String} target75 */76 exports.prototype['target'] = undefined;77 return exports;...

Full Screen

Full Screen

q4.js

Source:q4.js Github

copy

Full Screen

1var btn = document.getElementById("btn-calcular");2var fieldQtde = document.getElementById("field-1");3var fieldValorMin = document.getElementById("field-2");4var fieldValorMax = document.getElementById("field-3");5//6btn.addEventListener("click", () => {7 var collection = [];8 //colocando os valores minimo e maximo em posições aleatórias9 collection[ Math.floor(Math.random() * fieldQtde.value + 1) ] = fieldValorMin.value;10 collection[ Math.floor(Math.random() * fieldQtde.value + 1) ] = fieldValorMax.value;11 fillArray(collection, fieldQtde.value, fieldValorMax.value, fieldValorMin);12 console.log("teste: ", collection);13});14function fillArray(collection, qtde, max, min) {15 // Preenchendo as demais posições com fieldQtde.value números que não existam no array16 do {17 let pushTarget = getRandomInt(min, max);18 if (collection.includes(pushTarget)) {19 collection.push(pushTarget);20 } else {21 let pushTarget = getRandomInt(min, max);22 collection.push(pushTarget);23 }24 } while (!isEmptyIndex(collection));25}26// Verifica se existe posição vazia no array27function isEmptyIndex(array) {28 for (let i = 0; i < array.length; i++) {29 if (typeof array[ i ] === "undefined") {30 return true;31 }32 }33 return false;34}35function getRandomInt(min, max) {36 min = Math.ceil(min);37 max = Math.floor(max);38 return Math.floor(Math.random() * (max - min + 1)) + min;...

Full Screen

Full Screen

Watcher.js

Source:Watcher.js Github

copy

Full Screen

...8 this.getter = expOrFn9 this.get(vm)10 }11 get (vm) {12 pushTarget(this)13 const value = this.getter.call(vm, vm)14 popTarget()15 return value16 }17 addDep(dep) {18 dep.addSub(this)19 }20 update() {21 console.log('data发生改变,组件需要更新')22 }23}...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.evaluate(() => {7 const target = document.createElement('div');8 target.textContent = 'Hello World';9 document.body.appendChild(target);10 });11 await page.evaluate(() => {12 const target = document.createElement('div');13 target.textContent = 'Hello World 2';14 document.body.appendChild(target);15 });16 await page.evaluate(() => {17 const target = document.createElement('div');18 target.textContent = 'Hello World 3';19 document.body.appendChild(target);20 });21 await page.evaluate(() => {22 const target = document.createElement('div');23 target.textContent = 'Hello World 4';24 document.body.appendChild(target);25 });26 await page.evaluate(() => {27 const target = document.createElement('div');28 target.textContent = 'Hello World 5';29 document.body.appendChild(target);30 });31 await page.evaluate(() => {32 const target = document.createElement('div');33 target.textContent = 'Hello World 6';34 document.body.appendChild(target);35 });36 await page.evaluate(() => {37 const target = document.createElement('div');38 target.textContent = 'Hello World 7';39 document.body.appendChild(target);40 });41 await page.evaluate(() => {42 const target = document.createElement('div');43 target.textContent = 'Hello World 8';44 document.body.appendChild(target);45 });46 await page.evaluate(() => {47 const target = document.createElement('div');48 target.textContent = 'Hello World 9';49 document.body.appendChild(target);50 });51 await page.evaluate(() => {52 const target = document.createElement('div');53 target.textContent = 'Hello World 10';54 document.body.appendChild(target);55 });56 await page.evaluate(() => {57 const target = document.createElement('div');58 target.textContent = 'Hello World 11';59 document.body.appendChild(target);60 });61 await page.evaluate(() => {62 const target = document.createElement('div');63 target.textContent = 'Hello World 12';64 document.body.appendChild(target);65 });66 await page.evaluate(() => {67 const target = document.createElement('div');68 target.textContent = 'Hello World 13';69 document.body.appendChild(target);70 });71 await page.evaluate(() => {

Full Screen

Using AI Code Generation

copy

Full Screen

1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.evaluate(() => {7 window.__playwright__internal__api__pushTarget(newPage);8 });9 await page.bringToFront();10 await page.screenshot({ path: 'youtube.png' });11 await browser.close();12})();13const { chromium } = require('playwright');14(async () => {15 const browser = await chromium.launch();16 const context = await browser.newContext();17 const page = await context.newPage();18 await page.evaluate(() => {19 window.__playwright__internal__api__pushTarget(newPage);20 });21 await page.bringToFront();22 await page.screenshot({ path: 'youtube.png' });23 await page.evaluate(() => {24 window.__playwright__internal__api__popTarget();25 });26 await page.screenshot({ path: 'google.png' });27 await browser.close();28})();29#### playwright.executablePath()30#### playwright.launch([options])

Full Screen

Using AI Code Generation

copy

Full Screen

1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch({headless: false});4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.fill('#tsf > div:nth-child(2) > div > div.RNNXgb > div > div.a4bIc > input', 'Playwright');7 await page.click('text=Google Search');8 await page.waitForTimeout(3000);9 await page.click('text=Playwright');10 await page.waitForTimeout(3000);11 await page.goBack();12 await page.waitForTimeout(3000);13 await page.goForward();14 await page.waitForTimeout(3000);15 await page.reload();16 await page.waitForTimeout(3000);17 await browser.close();18})();19const { chromium } = require('playwright');20(async () => {21 const browser = await chromium.launch({headless: false});22 const context = await browser.newContext();23 const page = await context.newPage();24 await page.fill('#tsf > div:nth-child(2) > div > div.RNNXgb > div > div.a4bIc > input', 'Playwright');25 await page.click('text=Google Search');26 await page.waitForTimeout(3000);27 await page.click('text=Playwright');28 await page.waitForTimeout(3000);29 await page.goBack();30 await page.waitForTimeout(3000);31 await page.goForward();32 await page.waitForTimeout(3000);33 await page.reload();34 await page.waitForTimeout(3000);35 await browser.close();36})();37const { chromium } = require('playwright');38(async () => {39 const browser = await chromium.launch({headless: false});40 const context = await browser.newContext();41 const page = await context.newPage();42 await page.fill('#tsf > div:nth-child(2) > div > div.RNNXgb > div > div.a4bIc > input', 'Playwright');43 await page.click('text

Full Screen

Using AI Code Generation

copy

Full Screen

1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 const { target } = await page._delegate._connection.send('Target.createTarget', {7 });8 const newPage = await context._browserContext._delegate._connection._sessions.get(target.targetId).page();9 console.log(newPage.url());10 await browser.close();11})();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { chromium } = require('playwright');2const { pushTarget } = require('playwright/lib/server/chromium/crBrowser');3(async () => {4 const browser = await chromium.launch();5 const page = await browser.newPage();6 const target = await pushTarget(page);7 console.log(target);8 await browser.close();9})();10{ targetId: 'target-1',11 Browser {12 { _timeoutSettings: TimeoutSettings { _defaultTimeout: 30000 },13 _logger: Logger {},14 _chromiumSandbox: true },15 BrowserContext {16 _timeoutSettings: TimeoutSettings { _defaultTimeout: 30000 },17 _logger: Logger {},18 _permissions: {},19 _pageBindings: Map {},20 _closePromise: Promise { <pending> },21 _ownedPages: Set {},22 _ownedWorkers: Set {},23 _crPages: Map {},

Full Screen

Using AI Code Generation

copy

Full Screen

1const { chromium } = require('playwright');2const { pushTarget } = require('playwright/lib/client/CDPSession');3(async () => {4 const browser = await chromium.launch();5 const context = await browser.newContext();6 const page = await context.newPage();7 await browser.close();8})();9const { helper } = require('./helper');10const { assert } = require('./helper');11const { events } = require('./events');12const { Protocol } = require('./protocol');13const { Target } = Protocol;14const kBrowserContexts = Symbol('browserContexts');15class CDPSession {16 constructor(connection, target, ignoreHTTPSErrors, defaultViewport) {17 this._connection = connection;18 this._target = target;19 this._ignoreHTTPSErrors = ignoreHTTPSErrors;20 this._defaultViewport = defaultViewport;21 this._eventListeners = [];22 this._callbacks = new Map();23 this._lastId = 0;24 this._connection.on('Target.receivedMessageFromTarget', this._onMessage.bind(this));25 }26 async _onMessage(message) {27 if (message.targetId !== this._target._targetId)28 return;29 const object = JSON.parse(message.message);30 if (object.id) {31 const callback = this._callbacks.get(object.id);32 assert(callback, 'INTERNAL ERROR: missing callback for id=' + object.id);33 this._callbacks.delete(object.id);34 callback(object.error, object.result);35 return;36 }37 this.emit(object.method, object.params);38 }39 async send(method, params) {40 const id = ++this._lastId;41 this._connection.send('Target.sendMessageToTarget', {42 message: JSON.stringify({ id, method, params })43 });44 return new Promise((fulfill, reject) => {45 this._callbacks.set(id, (error, result) => {46 if (error)47 reject(new Error('Protocol error (' + method + '): ' + error.message));48 fulfill(result);49 });50 });51 }52 async detach() {53 helper.removeEventListeners(this._eventListeners);

Full Screen

Using AI Code Generation

copy

Full Screen

1const { chromium, webkit, firefox } = require("playwright");2const { pushTarget } = require("playwright/lib/server/browserContext");3const browser = await chromium.launch();4const context = await browser.newContext({5});6const page = await context.newPage();7await pushTarget(page);8await page.screenshot({ path: "google.png" });9await browser.close();10const { chromium, webkit, firefox } = require("playwright");11const { pushTarget } = require("playwright/lib/server/browserContext");12const browser = await chromium.launch();13const context = await browser.newContext({14});15const page = await context.newPage();16await pushTarget(page);17await page.screenshot({ path: "google.png" });18await browser.close();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { PlaywrightInternal } = require("playwright");2const { chromium } = require("playwright");3const { test } = require("@playwright/test");4test.describe("test", () => {5 test("test", async ({ page }) => {6 const internal = new PlaywrightInternal(chromium);7 const context = await internal._launchServerAndContext();8 const page1 = await context.newPage();9 await internal.pushTarget(page1);10 await page1.waitForSelector("input");11 await page1.click("input");12 await page1.fill("input", "Hello World");13 await page1.keyboard.press("Enter");14 await page1.waitForSelector("text=Hello World");15 await page1.close();16 });17});18const { test } = require("@playwright/test");19test("test", async ({ page }) => {20 await page.waitForSelector("input");21 await page.click("input");22 await page.fill("input", "Hello World");23 await page.keyboard.press("Enter");24 await page.waitForSelector("text=Hello World");25});

Full Screen

Using AI Code Generation

copy

Full Screen

1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 const input = await page.$('input');7 const target = await input.evaluateHandle((element) => {8 return element._page._delegate._delegate._session._connection._transport._session._target._targetInfo.targetId;9 });10 console.log(await target.jsonVa

Full Screen

Playwright tutorial

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.

Chapters:

  1. What is Playwright : Playwright is comparatively new but has gained good popularity. Get to know some history of the Playwright with some interesting facts connected with it.
  2. How To Install Playwright : Learn in detail about what basic configuration and dependencies are required for installing Playwright and run a test. Get a step-by-step direction for installing the Playwright automation framework.
  3. Playwright Futuristic Features: Launched in 2020, Playwright gained huge popularity quickly because of some obliging features such as Playwright Test Generator and Inspector, Playwright Reporter, Playwright auto-waiting mechanism and etc. Read up on those features to master Playwright testing.
  4. What is Component Testing: Component testing in Playwright is a unique feature that allows a tester to test a single component of a web application without integrating them with other elements. Learn how to perform Component testing on the Playwright automation framework.
  5. Inputs And Buttons In Playwright: Every website has Input boxes and buttons; learn about testing inputs and buttons with different scenarios and examples.
  6. Functions and Selectors in Playwright: Learn how to launch the Chromium browser with Playwright. Also, gain a better understanding of some important functions like “BrowserContext,” which allows you to run multiple browser sessions, and “newPage” which interacts with a page.
  7. Handling Alerts and Dropdowns in Playwright : Playwright interact with different types of alerts and pop-ups, such as simple, confirmation, and prompt, and different types of dropdowns, such as single selector and multi-selector get your hands-on with handling alerts and dropdown in Playright testing.
  8. Playwright vs Puppeteer: Get to know about the difference between two testing frameworks and how they are different than one another, which browsers they support, and what features they provide.
  9. Run Playwright Tests on LambdaTest: Playwright testing with LambdaTest leverages test performance to the utmost. You can run multiple Playwright tests in Parallel with the LammbdaTest test cloud. Get a step-by-step guide to run your Playwright test on the LambdaTest platform.
  10. Playwright Python Tutorial: Playwright automation framework support all major languages such as Python, JavaScript, TypeScript, .NET and etc. However, there are various advantages to Python end-to-end testing with Playwright because of its versatile utility. Get the hang of Playwright python testing with this chapter.
  11. Playwright End To End Testing Tutorial: Get your hands on with Playwright end-to-end testing and learn to use some exciting features such as TraceViewer, Debugging, Networking, Component testing, Visual testing, and many more.
  12. Playwright Video Tutorial: Watch the video tutorials on Playwright testing from experts and get a consecutive in-depth explanation of Playwright automation testing.

Run Playwright Internal automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful