Best JavaScript code snippet using playwright-internal
format-test.js
Source: format-test.js
1"use strict";2const { TEST_STANDALONE } = process.env;3const fs = require("fs");4const path = require("path");5const prettier = !TEST_STANDALONE6 ? require("prettier-local")7 : require("prettier-standalone");8const checkParsers = require("./utils/check-parsers.js");9const createSnapshot = require("./utils/create-snapshot.js");10const visualizeEndOfLine = require("./utils/visualize-end-of-line.js");11const consistentEndOfLine = require("./utils/consistent-end-of-line.js");12const stringifyOptionsForTitle = require("./utils/stringify-options-for-title.js");13const { FULL_TEST } = process.env;14const BOM = "\uFEFF";15const CURSOR_PLACEHOLDER = "<|>";16const RANGE_START_PLACEHOLDER = "<<<PRETTIER_RANGE_START>>>";17const RANGE_END_PLACEHOLDER = "<<<PRETTIER_RANGE_END>>>";18// TODO: these test files need fix19const unstableTests = new Map(20 [21 "js/class-comment/misc.js",22 ["js/comments/dangling_array.js", (options) => options.semi === false],23 ["js/comments/jsx.js", (options) => options.semi === false],24 "js/comments/return-statement.js",25 "js/comments/tagged-template-literal.js",26 "markdown/spec/example-234.md",27 "markdown/spec/example-235.md",28 "html/multiparser/js/script-tag-escaping.html",29 [30 "js/multiparser-markdown/codeblock.js",31 (options) => options.proseWrap === "always",32 ],33 ["js/no-semi/comments.js", (options) => options.semi === false],34 ["flow/no-semi/comments.js", (options) => options.semi === false],35 "typescript/prettier-ignore/mapped-types.ts",36 "js/comments/html-like/comment.js",37 ].map((fixture) => {38 const [file, isUnstable = () => true] = Array.isArray(fixture)39 ? fixture40 : [fixture];41 return [path.join(__dirname, "../format/", file), isUnstable];42 })43);44const unstableAstTests = new Map();45const espreeDisabledTests = new Set(46 [47 // These tests only work for `babel`48 "comments-closure-typecast",49 ].map((directory) => path.join(__dirname, "../format/js", directory))50);51const meriyahDisabledTests = espreeDisabledTests;52const isUnstable = (filename, options) => {53 const testFunction = unstableTests.get(filename);54 if (!testFunction) {55 return false;56 }57 return testFunction(options);58};59const isAstUnstable = (filename, options) => {60 const testFunction = unstableAstTests.get(filename);61 if (!testFunction) {62 return false;63 }64 return testFunction(options);65};66const shouldThrowOnFormat = (filename, options) => {67 const { errors = {} } = options;68 if (errors === true) {69 return true;70 }71 const files = errors[options.parser];72 if (files === true || (Array.isArray(files) && files.includes(filename))) {73 return true;74 }75 return false;76};77const isTestDirectory = (dirname, name) =>78 (dirname + path.sep).startsWith(79 path.join(__dirname, "../format", name) + path.sep80 );81function runSpec(fixtures, parsers, options) {82 let { dirname, snippets = [] } =83 typeof fixtures === "string" ? { dirname: fixtures } : fixtures;84 // `IS_PARSER_INFERENCE_TESTS` mean to test `inferParser` on `standalone`85 const IS_PARSER_INFERENCE_TESTS = isTestDirectory(86 dirname,87 "misc/parser-inference"88 );89 // `IS_ERROR_TESTS` mean to watch errors like:90 // - syntax parser hasn't supported yet91 // - syntax errors that should throws92 const IS_ERROR_TESTS = isTestDirectory(dirname, "misc/errors");93 if (IS_ERROR_TESTS) {94 options = { errors: true, ...options };95 }96 const IS_TYPESCRIPT_ONLY_TEST = isTestDirectory(97 dirname,98 "misc/typescript-only"99 );100 if (IS_PARSER_INFERENCE_TESTS) {101 parsers = [undefined];102 }103 snippets = snippets.map((test, index) => {104 test = typeof test === "string" ? { code: test } : test;105 return {106 ...test,107 name: `snippet: ${test.name || `#${index}`}`,108 };109 });110 const files = fs111 .readdirSync(dirname, { withFileTypes: true })112 .map((file) => {113 const basename = file.name;114 const filename = path.join(dirname, basename);115 if (116 path.extname(basename) === ".snap" ||117 !file.isFile() ||118 basename[0] === "." ||119 basename === "jsfmt.spec.js" ||120 // VSCode creates this file sometime https://github.com/microsoft/vscode/issues/105191121 basename === "debug.log"122 ) {123 return;124 }125 const text = fs.readFileSync(filename, "utf8");126 return {127 name: basename,128 filename,129 code: text,130 };131 })132 .filter(Boolean);133 // Make sure tests are in correct location134 if (process.env.CHECK_TEST_PARSERS) {135 if (!Array.isArray(parsers) || parsers.length === 0) {136 throw new Error(`No parsers were specified for ${dirname}`);137 }138 checkParsers({ dirname, files }, parsers);139 }140 const [parser] = parsers;141 const allParsers = [...parsers];142 if (!IS_ERROR_TESTS) {143 if (144 parsers.includes("typescript") &&145 !parsers.includes("babel-ts") &&146 !IS_TYPESCRIPT_ONLY_TEST147 ) {148 allParsers.push("babel-ts");149 }150 if (parsers.includes("babel") && isTestDirectory(dirname, "js")) {151 if (!parsers.includes("espree") && !espreeDisabledTests.has(dirname)) {152 allParsers.push("espree");153 }154 if (!parsers.includes("meriyah") && !meriyahDisabledTests.has(dirname)) {155 allParsers.push("meriyah");156 }157 }158 if (parsers.includes("babel") && !parsers.includes("__babel_estree")) {159 allParsers.push("__babel_estree");160 }161 }162 const stringifiedOptions = stringifyOptionsForTitle(options);163 for (const { name, filename, code, output } of [...files, ...snippets]) {164 const title = `${name}${165 stringifiedOptions ? ` - ${stringifiedOptions}` : ""166 }`;167 describe(title, () => {168 const formatOptions = {169 printWidth: 80,170 ...options,171 filepath: filename,172 parser,173 };174 const mainParserFormatResult = shouldThrowOnFormat(name, formatOptions)175 ? { options: formatOptions, error: true }176 : format(code, formatOptions);177 for (const currentParser of allParsers) {178 runTest({179 parsers,180 name,181 filename,182 code,183 output,184 parser: currentParser,185 mainParserFormatResult,186 mainParserFormatOptions: formatOptions,187 });188 }189 });190 }191}192function runTest({193 parsers,194 name,195 filename,196 code,197 output,198 parser,199 mainParserFormatResult,200 mainParserFormatOptions,201}) {202 let formatOptions = mainParserFormatOptions;203 let formatResult = mainParserFormatResult;204 let formatTestTitle = "format";205 // Verify parsers or error tests206 if (207 mainParserFormatResult.error ||208 mainParserFormatOptions.parser !== parser209 ) {210 formatTestTitle = `[${parser}] format`;211 formatOptions = { ...mainParserFormatResult.options, parser };212 const runFormat = () => format(code, formatOptions);213 if (shouldThrowOnFormat(name, formatOptions)) {214 test(formatTestTitle, () => {215 expect(runFormat).toThrowErrorMatchingSnapshot();216 });217 return;218 }219 // Verify parsers format result should be the same as main parser220 output = mainParserFormatResult.outputWithCursor;221 formatResult = runFormat();222 }223 test(formatTestTitle, () => {224 // Make sure output has consistent EOL225 expect(formatResult.eolVisualizedOutput).toEqual(226 visualizeEndOfLine(consistentEndOfLine(formatResult.outputWithCursor))227 );228 // The result is assert to equals to `output`229 if (typeof output === "string") {230 expect(formatResult.eolVisualizedOutput).toEqual(231 visualizeEndOfLine(output)232 );233 return;234 }235 // All parsers have the same result, only snapshot the result from main parser236 expect(237 createSnapshot(formatResult, {238 parsers,239 formatOptions,240 CURSOR_PLACEHOLDER,241 })242 ).toMatchSnapshot();243 });244 if (!FULL_TEST) {245 return;246 }247 const isUnstableTest = isUnstable(filename, formatOptions);248 if (249 (formatResult.changed || isUnstableTest) &&250 // No range and cursor251 formatResult.input === code252 ) {253 test(`[${parser}] second format`, () => {254 const { eolVisualizedOutput: firstOutput, output } = formatResult;255 const { eolVisualizedOutput: secondOutput } = format(256 output,257 formatOptions258 );259 if (isUnstableTest) {260 // To keep eye on failed tests, this assert never supposed to pass,261 // if it fails, just remove the file from `unstableTests`262 expect(secondOutput).not.toEqual(firstOutput);263 } else {264 expect(secondOutput).toEqual(firstOutput);265 }266 });267 }268 const isAstUnstableTest = isAstUnstable(filename, formatOptions);269 // Some parsers skip parsing empty files270 if (formatResult.changed && code.trim()) {271 test(`[${parser}] compare AST`, () => {272 const { input, output } = formatResult;273 const originalAst = parse(input, formatOptions);274 const formattedAst = parse(output, formatOptions);275 if (isAstUnstableTest) {276 expect(formattedAst).not.toEqual(originalAst);277 } else {278 expect(formattedAst).toEqual(originalAst);279 }280 });281 }282 if (!shouldSkipEolTest(code, formatResult.options)) {283 for (const eol of ["\r\n", "\r"]) {284 test(`[${parser}] EOL ${JSON.stringify(eol)}`, () => {285 const output = format(286 code.replace(/\n/g, eol),287 formatOptions288 ).eolVisualizedOutput;289 // Only if `endOfLine: "auto"` the result will be different290 const expected =291 formatOptions.endOfLine === "auto"292 ? visualizeEndOfLine(293 // All `code` use `LF`, so the `eol` of result is always `LF`294 formatResult.outputWithCursor.replace(/\n/g, eol)295 )296 : formatResult.eolVisualizedOutput;297 expect(output).toEqual(expected);298 });299 }300 }301 if (code.charAt(0) !== BOM) {302 test(`[${parser}] BOM`, () => {303 const output = format(BOM + code, formatOptions).eolVisualizedOutput;304 const expected = BOM + formatResult.eolVisualizedOutput;305 expect(output).toEqual(expected);306 });307 }308}309function shouldSkipEolTest(code, options) {310 if (code.includes("\r")) {311 return true;312 }313 const { requirePragma, rangeStart, rangeEnd } = options;314 if (requirePragma) {315 return true;316 }317 if (318 typeof rangeStart === "number" &&319 typeof rangeEnd === "number" &&320 rangeStart >= rangeEnd321 ) {322 return true;323 }324 return false;325}326function parse(source, options) {327 return prettier.__debug.parse(source, options, /* massage */ true).ast;328}329const indexProperties = [330 {331 property: "cursorOffset",332 placeholder: CURSOR_PLACEHOLDER,333 },334 {335 property: "rangeStart",336 placeholder: RANGE_START_PLACEHOLDER,337 },338 {339 property: "rangeEnd",340 placeholder: RANGE_END_PLACEHOLDER,341 },342];343function replacePlaceholders(originalText, originalOptions) {344 const indexes = indexProperties345 .map(({ property, placeholder }) => {346 const value = originalText.indexOf(placeholder);347 return value === -1 ? undefined : { property, value, placeholder };348 })349 .filter(Boolean)350 .sort((a, b) => a.value - b.value);351 const options = { ...originalOptions };352 let text = originalText;353 let offset = 0;354 for (const { property, value, placeholder } of indexes) {355 text = text.replace(placeholder, "");356 options[property] = value + offset;357 offset -= placeholder.length;358 }359 return { text, options };360}361const insertCursor = (text, cursorOffset) =>362 cursorOffset >= 0363 ? text.slice(0, cursorOffset) +364 CURSOR_PLACEHOLDER +365 text.slice(cursorOffset)366 : text;367function format(originalText, originalOptions) {368 const { text: input, options } = replacePlaceholders(369 originalText,370 originalOptions371 );372 const inputWithCursor = insertCursor(input, options.cursorOffset);373 const { formatted: output, cursorOffset } = prettier.formatWithCursor(374 input,375 options376 );377 const outputWithCursor = insertCursor(output, cursorOffset);378 const eolVisualizedOutput = visualizeEndOfLine(outputWithCursor);379 const changed = outputWithCursor !== inputWithCursor;380 return {381 changed,382 options,383 input,384 inputWithCursor,385 output,386 outputWithCursor,387 eolVisualizedOutput,388 };389}...
run_spec.js
Source: run_spec.js
1"use strict";2const { TEST_STANDALONE } = process.env;3const fs = require("fs");4const path = require("path");5const prettier = !TEST_STANDALONE6 ? require("prettier-local")7 : require("prettier-standalone");8const checkParsers = require("./utils/check-parsers");9const createSnapshot = require("./utils/create-snapshot");10const visualizeEndOfLine = require("./utils/visualize-end-of-line");11const consistentEndOfLine = require("./utils/consistent-end-of-line");12const stringifyOptionsForTitle = require("./utils/stringify-options-for-title");13const { FULL_TEST } = process.env;14const BOM = "\uFEFF";15const CURSOR_PLACEHOLDER = "<|>";16const RANGE_START_PLACEHOLDER = "<<<PRETTIER_RANGE_START>>>";17const RANGE_END_PLACEHOLDER = "<<<PRETTIER_RANGE_END>>>";18// TODO: these test files need fix19const unstableTests = new Map(20 [21 "js/class-comment/misc.js",22 ["js/comments/dangling_array.js", (options) => options.semi === false],23 ["js/comments/jsx.js", (options) => options.semi === false],24 "js/comments/return-statement.js",25 "js/comments/tagged-template-literal.js",26 "markdown/spec/example-234.md",27 "markdown/spec/example-235.md",28 "html/multiparser/js/script-tag-escaping.html",29 [30 "js/multiparser-markdown/codeblock.js",31 (options) => options.proseWrap === "always",32 ],33 ["js/no-semi/comments.js", (options) => options.semi === false],34 ["flow/no-semi/comments.js", (options) => options.semi === false],35 "typescript/prettier-ignore/mapped-types.ts",36 "js/comments/html-like/comment.js",37 ].map((fixture) => {38 const [file, isUnstable = () => true] = Array.isArray(fixture)39 ? fixture40 : [fixture];41 return [path.join(__dirname, "../tests/", file), isUnstable];42 })43);44const unstableAstTests = new Map();45const espreeDisabledTests = new Set(46 [47 // These tests only work for `babel`48 "comments-closure-typecast",49 ].map((directory) => path.join(__dirname, "../tests/js", directory))50);51const meriyahDisabledTests = espreeDisabledTests;52const isUnstable = (filename, options) => {53 const testFunction = unstableTests.get(filename);54 if (!testFunction) {55 return false;56 }57 return testFunction(options);58};59const isAstUnstable = (filename, options) => {60 const testFunction = unstableAstTests.get(filename);61 if (!testFunction) {62 return false;63 }64 return testFunction(options);65};66const shouldThrowOnFormat = (filename, options) => {67 const { errors = {} } = options;68 if (errors === true) {69 return true;70 }71 const files = errors[options.parser];72 if (files === true || (Array.isArray(files) && files.includes(filename))) {73 return true;74 }75 return false;76};77const isTestDirectory = (dirname, name) =>78 (dirname + path.sep).startsWith(79 path.join(__dirname, "../tests", name) + path.sep80 );81function runSpec(fixtures, parsers, options) {82 let { dirname, snippets = [] } =83 typeof fixtures === "string" ? { dirname: fixtures } : fixtures;84 // `IS_PARSER_INFERENCE_TESTS` mean to test `inferParser` on `standalone`85 const IS_PARSER_INFERENCE_TESTS = isTestDirectory(86 dirname,87 "misc/parser-inference"88 );89 // `IS_ERROR_TESTS` mean to watch errors like:90 // - syntax parser hasn't supported yet91 // - syntax errors that should throws92 const IS_ERROR_TESTS = isTestDirectory(dirname, "misc/errors");93 if (IS_ERROR_TESTS) {94 options = { errors: true, ...options };95 }96 const IS_TYPESCRIPT_ONLY_TEST = isTestDirectory(97 dirname,98 "misc/typescript-only"99 );100 if (IS_PARSER_INFERENCE_TESTS) {101 parsers = [undefined];102 }103 snippets = snippets.map((test, index) => {104 test = typeof test === "string" ? { code: test } : test;105 return {106 ...test,107 name: `snippet: ${test.name || `#${index}`}`,108 };109 });110 const files = fs111 .readdirSync(dirname, { withFileTypes: true })112 .map((file) => {113 const basename = file.name;114 const filename = path.join(dirname, basename);115 if (116 path.extname(basename) === ".snap" ||117 !file.isFile() ||118 basename[0] === "." ||119 basename === "jsfmt.spec.js" ||120 // VSCode creates this file sometime https://github.com/microsoft/vscode/issues/105191121 basename === "debug.log"122 ) {123 return;124 }125 const text = fs.readFileSync(filename, "utf8");126 return {127 name: basename,128 filename,129 code: text,130 };131 })132 .filter(Boolean);133 // Make sure tests are in correct location134 if (process.env.CHECK_TEST_PARSERS) {135 if (!Array.isArray(parsers) || parsers.length === 0) {136 throw new Error(`No parsers were specified for ${dirname}`);137 }138 checkParsers({ dirname, files }, parsers);139 }140 const [parser] = parsers;141 const allParsers = [...parsers];142 if (!IS_ERROR_TESTS) {143 if (144 parsers.includes("typescript") &&145 !parsers.includes("babel-ts") &&146 !IS_TYPESCRIPT_ONLY_TEST147 ) {148 allParsers.push("babel-ts");149 }150 if (parsers.includes("babel") && isTestDirectory(dirname, "js")) {151 if (!parsers.includes("espree") && !espreeDisabledTests.has(dirname)) {152 allParsers.push("espree");153 }154 if (!parsers.includes("meriyah") && !meriyahDisabledTests.has(dirname)) {155 allParsers.push("meriyah");156 }157 }158 }159 const stringifiedOptions = stringifyOptionsForTitle(options);160 for (const { name, filename, code, output } of [...files, ...snippets]) {161 const title = `${name}${162 stringifiedOptions ? ` - ${stringifiedOptions}` : ""163 }`;164 describe(title, () => {165 const formatOptions = {166 printWidth: 80,167 ...options,168 filepath: filename,169 parser,170 };171 const mainParserFormatResult = shouldThrowOnFormat(name, formatOptions)172 ? { options: formatOptions, error: true }173 : format(code, formatOptions);174 for (const currentParser of allParsers) {175 runTest({176 parsers,177 name,178 filename,179 code,180 output,181 parser: currentParser,182 mainParserFormatResult,183 mainParserFormatOptions: formatOptions,184 });185 }186 });187 }188}189function runTest({190 parsers,191 name,192 filename,193 code,194 output,195 parser,196 mainParserFormatResult,197 mainParserFormatOptions,198}) {199 let formatOptions = mainParserFormatOptions;200 let formatResult = mainParserFormatResult;201 let formatTestTitle = "format";202 // Verify parsers or error tests203 if (204 mainParserFormatResult.error ||205 mainParserFormatOptions.parser !== parser206 ) {207 formatTestTitle = `[${parser}] format`;208 formatOptions = { ...mainParserFormatResult.options, parser };209 const runFormat = () => format(code, formatOptions);210 if (shouldThrowOnFormat(name, formatOptions)) {211 test(formatTestTitle, () => {212 expect(runFormat).toThrowErrorMatchingSnapshot();213 });214 return;215 }216 // Verify parsers format result should be the same as main parser217 output = mainParserFormatResult.outputWithCursor;218 formatResult = runFormat();219 }220 test(formatTestTitle, () => {221 // Make sure output has consistent EOL222 expect(formatResult.eolVisualizedOutput).toEqual(223 visualizeEndOfLine(consistentEndOfLine(formatResult.outputWithCursor))224 );225 // The result is assert to equals to `output`226 if (typeof output === "string") {227 expect(formatResult.eolVisualizedOutput).toEqual(228 visualizeEndOfLine(output)229 );230 return;231 }232 // All parsers have the same result, only snapshot the result from main parser233 expect(234 createSnapshot(formatResult, {235 parsers,236 formatOptions,237 CURSOR_PLACEHOLDER,238 })239 ).toMatchSnapshot();240 });241 if (!FULL_TEST) {242 return;243 }244 const isUnstableTest = isUnstable(filename, formatOptions);245 if (246 (formatResult.changed || isUnstableTest) &&247 // No range and cursor248 formatResult.input === code249 ) {250 test(`[${parser}] second format`, () => {251 const { eolVisualizedOutput: firstOutput, output } = formatResult;252 const { eolVisualizedOutput: secondOutput } = format(253 output,254 formatOptions255 );256 if (isUnstableTest) {257 // To keep eye on failed tests, this assert never supposed to pass,258 // if it fails, just remove the file from `unstableTests`259 expect(secondOutput).not.toEqual(firstOutput);260 } else {261 expect(secondOutput).toEqual(firstOutput);262 }263 });264 }265 const isAstUnstableTest = isAstUnstable(filename, formatOptions);266 // Some parsers skip parsing empty files267 if (formatResult.changed && code.trim()) {268 test(`[${parser}] compare AST`, () => {269 const { input, output } = formatResult;270 const originalAst = parse(input, formatOptions);271 const formattedAst = parse(output, formatOptions);272 if (isAstUnstableTest) {273 expect(formattedAst).not.toEqual(originalAst);274 } else {275 expect(formattedAst).toEqual(originalAst);276 }277 });278 }279 if (!shouldSkipEolTest(code, formatResult.options)) {280 for (const eol of ["\r\n", "\r"]) {281 test(`[${parser}] EOL ${JSON.stringify(eol)}`, () => {282 const output = format(code.replace(/\n/g, eol), formatOptions)283 .eolVisualizedOutput;284 // Only if `endOfLine: "auto"` the result will be different285 const expected =286 formatOptions.endOfLine === "auto"287 ? visualizeEndOfLine(288 // All `code` use `LF`, so the `eol` of result is always `LF`289 formatResult.outputWithCursor.replace(/\n/g, eol)290 )291 : formatResult.eolVisualizedOutput;292 expect(output).toEqual(expected);293 });294 }295 }296 if (code.charAt(0) !== BOM) {297 test(`[${parser}] BOM`, () => {298 const output = format(BOM + code, formatOptions).eolVisualizedOutput;299 const expected = BOM + formatResult.eolVisualizedOutput;300 expect(output).toEqual(expected);301 });302 }303}304function shouldSkipEolTest(code, options) {305 if (code.includes("\r")) {306 return true;307 }308 const { requirePragma, rangeStart, rangeEnd } = options;309 if (requirePragma) {310 return true;311 }312 if (313 typeof rangeStart === "number" &&314 typeof rangeEnd === "number" &&315 rangeStart >= rangeEnd316 ) {317 return true;318 }319 return false;320}321function parse(source, options) {322 return prettier.__debug.parse(source, options, /* massage */ true).ast;323}324const indexProperties = [325 {326 property: "cursorOffset",327 placeholder: CURSOR_PLACEHOLDER,328 },329 {330 property: "rangeStart",331 placeholder: RANGE_START_PLACEHOLDER,332 },333 {334 property: "rangeEnd",335 placeholder: RANGE_END_PLACEHOLDER,336 },337];338function replacePlaceholders(originalText, originalOptions) {339 const indexes = indexProperties340 .map(({ property, placeholder }) => {341 const value = originalText.indexOf(placeholder);342 return value === -1 ? undefined : { property, value, placeholder };343 })344 .filter(Boolean)345 .sort((a, b) => a.value - b.value);346 const options = { ...originalOptions };347 let text = originalText;348 let offset = 0;349 for (const { property, value, placeholder } of indexes) {350 text = text.replace(placeholder, "");351 options[property] = value + offset;352 offset -= placeholder.length;353 }354 return { text, options };355}356const insertCursor = (text, cursorOffset) =>357 cursorOffset >= 0358 ? text.slice(0, cursorOffset) +359 CURSOR_PLACEHOLDER +360 text.slice(cursorOffset)361 : text;362function format(originalText, originalOptions) {363 const { text: input, options } = replacePlaceholders(364 originalText,365 originalOptions366 );367 const inputWithCursor = insertCursor(input, options.cursorOffset);368 const { formatted: output, cursorOffset } = prettier.formatWithCursor(369 input,370 options371 );372 const outputWithCursor = insertCursor(output, cursorOffset);373 const eolVisualizedOutput = visualizeEndOfLine(outputWithCursor);374 const changed = outputWithCursor !== inputWithCursor;375 return {376 changed,377 options,378 input,379 inputWithCursor,380 output,381 outputWithCursor,382 eolVisualizedOutput,383 };384}...
ReporterUtils.spec.js
Source: ReporterUtils.spec.js
...14 formatSuiteTitle,15 writeFile16} = require('../../src/ReporterUtils');17describe('Testing ReporterUtils.js', () => {18 describe('formatTestTitle()', () => {19 it('simple test', () => {20 const result = formatTestTitle({21 title: 'My title'22 }, {23 useFullTitle: true24 });25 expect(result).toBe('My title');26 });27 it('within a suite', () => {28 const result = formatTestTitle({29 title: 'My title',30 parent: {31 title: 'My suite'32 }33 }, {34 useFullTitle: true,35 titleSeparator: ' | '36 });37 expect(result).toBe('My suite | My title');38 });39 });40 describe('formatSuiteTitle()', () => {41 it('simple suite', () => {42 const result = formatSuiteTitle({...
playwright-formatters.js
Source: playwright-formatters.js
...98 if (line) line += " ";99 return line + gray(char.repeat(Math.max(0, 100 - line.length)));100}101function formatTestHeader(config, test, indent, index) {102 const title = formatTestTitle(config, test);103 const header = `${indent}${index ? index + ") " : ""}${title}`;104 return pad(header, "=");105}106function stepSuffix(step) {107 const stepTitles = step ? step.titlePath() : [];108 return stepTitles.map((t) => " ⺠" + t).join("");109}110function relativeTestPath(config, test) {111 return relative(config.rootDir, test.location.file) || _path.default.basename(test.location.file);112}113function formatResultFailure(test, result, initialIndent, highlightCode) {114 var _error;115 const resultTokens = [];116 if (result.status === "timedOut") {117 resultTokens.push("");118 resultTokens.push(indent(red(`Timeout of ${test.timeout}ms exceeded.`), initialIndent));119 }120 if (result.status === "passed" && test.expectedStatus === "failed") {121 resultTokens.push("");122 resultTokens.push(indent(red(`Expected to fail, but passed.`), initialIndent));123 }124 let error = undefined;125 if (result.error !== undefined) {126 error = formatError(result.error, highlightCode, test.location.file);127 resultTokens.push(indent(error.message, initialIndent));128 }129 return {130 tokens: resultTokens,131 position: (_error = error) === null || _error === void 0 ? void 0 : _error.position,132 };133}134function formatTestTitle(config, test, step) {135 // root, project, file, ...describes, test136 const [, projectName, , ...titles] = test.titlePath();137 const location = `${relativeTestPath(config, test)}:${test.location.line}:${test.location.column}`;138 const projectTitle = projectName ? `[${projectName}] ⺠` : "";139 return `${projectTitle}${location} ⺠${titles.join(" ⺠")}${stepSuffix(step)}`;140}141function formatFailure(config, test, options = {}) {142 const { index, includeStdio, includeAttachments = true, filePath } = options;143 const lines = [];144 const title = formatTestTitle(config, test);145 const annotations = [];146 const header = formatTestHeader(config, test, " ", index);147 lines.push(red(header));148 for (const result of test.results) {149 const resultLines = [];150 const { tokens: resultTokens, position } = formatResultFailure(test, result, " ", enabled);151 if (!resultTokens.length) continue;152 if (result.retry) {153 resultLines.push("");154 resultLines.push(gray(pad(` Retry #${result.retry}`, "-")));155 }156 resultLines.push(...resultTokens);157 if (includeAttachments) {158 for (let i = 0; i < result.attachments.length; ++i) {...
list.js
Source: list.js
1"use strict";2Object.defineProperty(exports, "__esModule", {3 value: true4});5exports.default = void 0;6var _safe = _interopRequireDefault(require("colors/safe"));7var _ms = _interopRequireDefault(require("ms"));8var _base = require("./base");9function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }10/**11 * Copyright (c) Microsoft Corporation.12 *13 * Licensed under the Apache License, Version 2.0 (the "License");14 * you may not use this file except in compliance with the License.15 * You may obtain a copy of the License at16 *17 * http://www.apache.org/licenses/LICENSE-2.018 *19 * Unless required by applicable law or agreed to in writing, software20 * distributed under the License is distributed on an "AS IS" BASIS,21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.22 * See the License for the specific language governing permissions and23 * limitations under the License.24 */25/* eslint-disable no-console */26// @ts-ignore27// Allow it in the Visual Studio Code Terminal and the new Windows Terminal28const DOES_NOT_SUPPORT_UTF8_IN_TERMINAL = process.platform === 'win32' && process.env.TERM_PROGRAM !== 'vscode' && !process.env.WT_SESSION;29const POSITIVE_STATUS_MARK = DOES_NOT_SUPPORT_UTF8_IN_TERMINAL ? 'ok' : 'â';30const NEGATIVE_STATUS_MARK = DOES_NOT_SUPPORT_UTF8_IN_TERMINAL ? 'x' : 'â';31class ListReporter extends _base.BaseReporter {32 constructor() {33 super();34 this._lastRow = 0;35 this._testRows = new Map();36 this._needNewLine = false;37 this._liveTerminal = void 0;38 this._liveTerminal = process.stdout.isTTY || process.env.PWTEST_SKIP_TEST_OUTPUT;39 }40 onBegin(config, suite) {41 super.onBegin(config, suite);42 console.log();43 }44 onTestBegin(test) {45 if (this._liveTerminal) {46 if (this._needNewLine) {47 this._needNewLine = false;48 process.stdout.write('\n');49 this._lastRow++;50 }51 process.stdout.write(' ' + _safe.default.gray((0, _base.formatTestTitle)(this.config, test)) + '\n');52 }53 this._testRows.set(test, this._lastRow++);54 }55 onStdOut(chunk, test, result) {56 super.onStdOut(chunk, test, result);57 this._dumpToStdio(test, chunk, process.stdout);58 }59 onStdErr(chunk, test, result) {60 super.onStdErr(chunk, test, result);61 this._dumpToStdio(test, chunk, process.stdout);62 }63 onStepBegin(test, result, step) {64 if (!this._liveTerminal) return;65 if (step.category !== 'test.step') return;66 this._updateTestLine(test, ' ' + _safe.default.gray((0, _base.formatTestTitle)(this.config, test, step)));67 }68 onStepEnd(test, result, step) {69 if (!this._liveTerminal) return;70 if (step.category !== 'test.step') return;71 this._updateTestLine(test, ' ' + _safe.default.gray((0, _base.formatTestTitle)(this.config, test, step.parent)));72 }73 _dumpToStdio(test, chunk, stream) {74 if (this.config.quiet) return;75 const text = chunk.toString('utf-8');76 this._needNewLine = text[text.length - 1] !== '\n';77 if (this._liveTerminal) {78 const newLineCount = text.split('\n').length - 1;79 this._lastRow += newLineCount;80 }81 stream.write(chunk);82 }83 onTestEnd(test, result) {84 super.onTestEnd(test, result);85 const duration = _safe.default.dim(` (${(0, _ms.default)(result.duration)})`);86 const title = (0, _base.formatTestTitle)(this.config, test);87 let text = '';88 if (result.status === 'skipped') {89 text = _safe.default.green(' - ') + _safe.default.cyan(title);90 } else {91 const statusMark = (' ' + (result.status === 'passed' ? POSITIVE_STATUS_MARK : NEGATIVE_STATUS_MARK)).padEnd(5);92 if (result.status === test.expectedStatus) text = '\u001b[2K\u001b[0G' + _safe.default.green(statusMark) + _safe.default.gray(title) + duration;else text = '\u001b[2K\u001b[0G' + _safe.default.red(statusMark + title) + duration;93 }94 if (this._liveTerminal) {95 this._updateTestLine(test, text);96 } else {97 if (this._needNewLine) {98 this._needNewLine = false;99 process.stdout.write('\n');100 }101 process.stdout.write(text);102 process.stdout.write('\n');103 }104 }105 _updateTestLine(test, line) {106 if (process.env.PWTEST_SKIP_TEST_OUTPUT) this._updateTestLineForTest(test, line);else this._updateTestLineForTTY(test, line);107 }108 _updateTestLineForTTY(test, line) {109 const testRow = this._testRows.get(test); // Go up if needed110 if (testRow !== this._lastRow) process.stdout.write(`\u001B[${this._lastRow - testRow}A`); // Erase line111 process.stdout.write('\u001B[2K');112 process.stdout.write(line); // Go down if needed.113 if (testRow !== this._lastRow) process.stdout.write(`\u001B[${this._lastRow - testRow}E`);114 }115 _updateTestLineForTest(test, line) {116 const testRow = this._testRows.get(test);117 process.stdout.write(testRow + ' : ' + line + '\n');118 }119 async onEnd(result) {120 await super.onEnd(result);121 process.stdout.write('\n');122 this.epilogue(true);123 }124}125var _default = ListReporter;...
WalletE2eLogsReporter.js
Source: WalletE2eLogsReporter.js
...22 this.collectWorkerExpenseLogs(chunk);23 }24 formatTestResult(test, result) {25 const duration = ` (${milliseconds(result.duration)})`;26 const title = formatTestTitle(this.config, test);27 let text = "";28 if (result.status === "skipped") {29 text = " - " + title;30 } else {31 const statusMark = (" " + (result.status === "passed" ? "â" : "â")).padEnd(5);32 text = statusMark + title + duration;33 }34 return text;35 }36 onTestEnd(test, result) {37 const text = this.formatTestResult(test, result);38 result.status === "passed" ? this.logger.info(text) : this.logger.error(text);39 }40 collectWorkerExpenseLogs(chunk) {...
ReporterUtils.js
Source: ReporterUtils.js
...89 * @param {object} test the Mocha test90 */91const formatTest = (node, test, options) => {92 const testNode = node.element('testCase')93 .attribute('name', formatTestTitle(test, options))94 .attribute('duration', test.duration || 0);95 switch (test.state) {96 case 'failed':97 if (test.err.name === 'AssertionError') {98 testNode.element('failure')99 .attribute('message', `${test.err.name}: ${test.err.message}`)100 .cdata(test.err.stack);101 } else {102 testNode.element('error')103 .attribute('message', `${test.err.name}: ${test.err.message}`)104 .cdata(test.err.stack);105 }106 break;107 case 'pending':...
line.js
Source: line.js
1"use strict";2Object.defineProperty(exports, "__esModule", {3 value: true4});5exports.default = void 0;6var _safe = _interopRequireDefault(require("colors/safe"));7var _base = require("./base");8function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }9/**10 * Copyright (c) Microsoft Corporation.11 *12 * Licensed under the Apache License, Version 2.0 (the "License");13 * you may not use this file except in compliance with the License.14 * You may obtain a copy of the License at15 *16 * http://www.apache.org/licenses/LICENSE-2.017 *18 * Unless required by applicable law or agreed to in writing, software19 * distributed under the License is distributed on an "AS IS" BASIS,20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.21 * See the License for the specific language governing permissions and22 * limitations under the License.23 */24class LineReporter extends _base.BaseReporter {25 constructor(...args) {26 super(...args);27 this._total = 0;28 this._current = 0;29 this._failures = 0;30 this._lastTest = void 0;31 }32 onBegin(config, suite) {33 super.onBegin(config, suite);34 this._total = suite.allTests().length;35 console.log();36 }37 onStdOut(chunk, test, result) {38 super.onStdOut(chunk, test, result);39 this._dumpToStdio(test, chunk, process.stdout);40 }41 onStdErr(chunk, test, result) {42 super.onStdErr(chunk, test, result);43 this._dumpToStdio(test, chunk, process.stderr);44 }45 _dumpToStdio(test, chunk, stream) {46 if (this.config.quiet) return;47 stream.write(`\u001B[1A\u001B[2K`);48 if (test && this._lastTest !== test) {49 // Write new header for the output.50 stream.write(_safe.default.gray((0, _base.formatTestTitle)(this.config, test) + `\n`));51 this._lastTest = test;52 }53 stream.write(chunk);54 console.log();55 }56 onTestEnd(test, result) {57 super.onTestEnd(test, result);58 const width = process.stdout.columns - 1;59 const title = `[${++this._current}/${this._total}] ${(0, _base.formatTestTitle)(this.config, test)}`.substring(0, width);60 process.stdout.write(`\u001B[1A\u001B[2K${title}\n`);61 if (!this.willRetry(test, result) && !test.ok()) {62 process.stdout.write(`\u001B[1A\u001B[2K`);63 console.log((0, _base.formatFailure)(this.config, test, ++this._failures));64 console.log();65 }66 }67 async onEnd(result) {68 process.stdout.write(`\u001B[1A\u001B[2K`);69 await super.onEnd(result);70 this.epilogue(false);71 }72}73var _default = LineReporter;...
Using AI Code Generation
1const { formatTestTitle } = require('@playwright/test/lib/test');2const { test } = require('@playwright/test');3test.describe('formatTestTitle', () => {4 test('should return formatted title', () => {5 const title = formatTestTitle('test', 'foo', 'bar', 'baz');6 expect(title).toBe('foo bar baz');7 });8});
Using AI Code Generation
1const { formatTestTitle } = require('@playwright/test');2const test = require('@playwright/test').test;3test('example test', async ({ page }) => {4 const formattedTitle = formatTestTitle('example test', 'my test suite');5 expect(formattedTitle).toBe('my test suite - example test');6});7test('example test', async ({ page }) => {8 const formattedTitle = formatTestTitle('example test', 'my test suite');9 expect(formattedTitle).toBe('my test suite - example test');10});11const { formatTestTitle } = require('@playwright/test');12const { Test, TestResult } = require('@playwright/test');13const { TestStatus } = require('@playwright/test');14const { TestResultStatus } = require('@playwright/test');15const { TestType } = require('@playwright/test');16const { TestRunner } = require('@playwright/test');17const { TestModifier } = require('@playwright/test');18const { TestStep } = require('@playwright/test');19const { TestFixtures } = require('@playwright/test');20const { FullConfig } = require('@playwright/test');21const { FullProject } = require('@playwright/test');22const { FullResult } = require('@playwright/test');23const { FullTestResult } = require('@playwright/test');24const { FullWorkerResult } = require('@playwright/test');25const { FullWorker } = require('@playwright/test');26const { PlaywrightTestArgs } = require('@playwright/test');27const { PlaywrightWorkerArgs } = require('@playwright/test');28const { PlaywrightWorker } = require('@playwright/test');29const { PlaywrightWorkerRunner } = require('@playwright/test');30const { PlaywrightWorkerRunnerArgs } = require('@playwright/test');31const { PlaywrightWorkerRunnerWorker } = require('@playwright/test');32const { PlaywrightWorkerRunnerWorkerArgs } = require('@playwright/test');33const { PlaywrightWorkerRunnerWorkerResult } = require('@playwright/test');34const { Playwright
Using AI Code Generation
1const { formatTestTitle } = require('@playwright/test');2const test = require('@playwright/test').test;3test('test', async ({ page }) => {4 console.log(formatTestTitle('test'));5});6const { formatTestTitle } = require('@playwright/test');7const test = require('@playwright/test').test;8test('test', async ({ page }) => {9 console.log(formatTestTitle('test', '_'));10});11const { formatTestTitle } = require('@playwright/test');12const test = require('@playwright/test').test;13test('test', async ({ page }) => {14 console.log(formatTestTitle('test', '_'));15});16const { formatTestTitle } = require('@playwright/test');17const test = require('@playwright/test').test;18test('test', async ({ page }) => {19 console.log(formatTestTitle('test', '_'));20});
Using AI Code Generation
1const { PlaywrightTest } = require('@playwright/test');2console.log(PlaywrightTest.formatTestTitle('test title', 'test title'));3const { PlaywrightTest } = require('@playwright/test');4console.log(PlaywrightTest.formatTestTitle('test title', 'test title'));5import { PlaywrightTest } from '@playwright/test';6console.log(PlaywrightTest.formatTestTitle('test title', 'test title'));7import { PlaywrightTest } from '@playwright/test';8console.log(PlaywrightTest.formatTestTitle('test title', 'test title'));9import { PlaywrightTest } from '@playwright/test';10console.log(PlaywrightTest.formatTestTitle('test title', 'test title'));11const { PlaywrightTest } = require('@playwright/test');12console.log(PlaywrightTest.formatTestTitle('test title', 'test title'));13const { PlaywrightTest } = require('@playwright/test');14console.log(PlaywrightTest.formatTestTitle('test title', 'test title'));15import { PlaywrightTest } from '@playwright/test';16console.log(PlaywrightTest.formatTestTitle('test title', 'test title'));17import { PlaywrightTest } from '@playwright/test';18console.log(PlaywrightTest.formatTestTitle('test title', 'test title'));
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!!