164 lines
5.5 KiB
JavaScript
164 lines
5.5 KiB
JavaScript
/**
|
|
* Copyright (c) Microsoft Corporation.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
/** @typedef {'Types'|'ReleaseNotesMd'} OutputType */
|
|
|
|
// @ts-check
|
|
const toKebabCase = require('lodash/kebabCase.js')
|
|
const Documentation = require('./documentation');
|
|
|
|
/**
|
|
* @param {string} languagePath
|
|
* @param {Documentation.Member} member
|
|
* @param {string} text
|
|
* @param {string=} paramOrOption
|
|
* @returns {string}
|
|
*/
|
|
function createMarkdownLink(languagePath, member, text, paramOrOption) {
|
|
if (!member.clazz)
|
|
throw new Error('Member without a class!');
|
|
const className = toKebabCase(member.clazz.name);
|
|
const memberName = toKebabCase(member.name);
|
|
let hash = null;
|
|
if (member.kind === 'property' || member.kind === 'method')
|
|
hash = `${className}-${memberName}`.toLowerCase();
|
|
else if (member.kind === 'event')
|
|
hash = `${className}-event-${memberName}`.toLowerCase();
|
|
if (paramOrOption)
|
|
hash += '-option-' + toKebabCase(paramOrOption).toLowerCase();
|
|
return `[${text}](https://playwright.dev${languagePath}/docs/api/class-${member.clazz.name.toLowerCase()}#${hash})`;
|
|
};
|
|
|
|
/**
|
|
* @param {string} languagePath
|
|
* @param {Documentation.Class} clazz
|
|
* @returns {string}
|
|
*/
|
|
function createClassMarkdownLink(languagePath, clazz) {
|
|
return `[${clazz.name}](https://playwright.dev${languagePath}/docs/api/class-${clazz.name.toLowerCase()})`;
|
|
};
|
|
|
|
/**
|
|
* @param {string} language
|
|
* @param {OutputType} outputType
|
|
* @returns {Documentation.Renderer}
|
|
*/
|
|
function docsLinkRendererForLanguage(language, outputType) {
|
|
const languagePath = languageToRelativeDocsPath(language);
|
|
return ({ clazz, member, param, option }) => {
|
|
if (clazz)
|
|
return createClassMarkdownLink(languagePath, clazz);
|
|
if (!member || !member.clazz)
|
|
throw new Error('Internal error');
|
|
if (param)
|
|
return createMarkdownLink(languagePath, member, `\`${param.alias}\``, param.name);
|
|
if (option)
|
|
return createMarkdownLink(languagePath, member, `\`${option.alias}\``, option.name);
|
|
const className = member.clazz.varName === 'playwrightAssertions' ? '' : member.clazz.varName + '.';
|
|
if (member.kind === 'method') {
|
|
const args = outputType === 'ReleaseNotesMd' ? '' : renderJSSignature(member.argsArray);
|
|
return createMarkdownLink(languagePath, member, `${formatClassName(className, language)}${member.alias}(${args})`);
|
|
}
|
|
if (member.kind === 'event')
|
|
return createMarkdownLink(languagePath, member, `${className}on('${member.alias.toLowerCase()}')`);
|
|
if (member.kind === 'property')
|
|
return createMarkdownLink(languagePath, member, `${className}${member.alias}`);
|
|
throw new Error('Unknown member kind ' + member.kind);
|
|
}
|
|
}
|
|
|
|
function languageToRelativeDocsPath(language) {
|
|
if (language === 'js')
|
|
return '';
|
|
if (language === 'csharp')
|
|
return '/dotnet';
|
|
if (language === 'python')
|
|
return '/python';
|
|
if (language === 'java')
|
|
return '/java';
|
|
throw new Error('Unexpected language ' + language);
|
|
}
|
|
|
|
function formatClassName(className, language) {
|
|
if (!className.endsWith('Assertions.'))
|
|
return className;
|
|
className = className.substring(0, className.length - 1)
|
|
if (language === 'js')
|
|
return `expect(${assertionArgument(className)}).`;
|
|
else if (language === 'csharp')
|
|
return `Expect(${assertionArgument(className)}).`;
|
|
else if (language === 'python')
|
|
return `expect(${assertionArgument(className)}).`;
|
|
else if (language === 'java')
|
|
return `assertThat(${assertionArgument(className)}).`;
|
|
throw new Error('Unexpected language ' + language);
|
|
}
|
|
|
|
function assertionArgument(className) {
|
|
switch (className.toLowerCase()) {
|
|
case 'locatorassertions': return 'locator';
|
|
case 'pageassertions': return 'page';
|
|
case 'genericassertions': return 'value';
|
|
case 'snapshotassertions': return 'value';
|
|
case 'apiresponseassertions': return 'response';
|
|
}
|
|
throw new Error(`Unexpected assertion class: ${className}`);
|
|
}
|
|
|
|
/**
|
|
* @param {Documentation.Member[]} args
|
|
*/
|
|
function renderJSSignature(args) {
|
|
const tokens = [];
|
|
let hasOptional = false;
|
|
for (const arg of args) {
|
|
const name = arg.alias;
|
|
const optional = !arg.required;
|
|
if (tokens.length) {
|
|
if (optional && !hasOptional)
|
|
tokens.push(`[, ${name}`);
|
|
else
|
|
tokens.push(`, ${name}`);
|
|
} else {
|
|
if (optional && !hasOptional)
|
|
tokens.push(`[${name}`);
|
|
else
|
|
tokens.push(`${name}`);
|
|
}
|
|
hasOptional = hasOptional || optional;
|
|
}
|
|
if (hasOptional)
|
|
tokens.push(']');
|
|
return tokens.join('');
|
|
}
|
|
|
|
/**
|
|
* @param {string} content
|
|
* @param {string} languagePath
|
|
* @param {string} relativePath
|
|
* @returns {string}
|
|
*/
|
|
function renderPlaywrightDevLinks(content, languagePath, relativePath) {
|
|
return content.replace(/\[([^\]]+)\]\((\.[^\)]+)\)/g, (match, p1, p2) => {
|
|
return `[${p1}](${new URL(p2.replace('.md', ''), `https://playwright.dev${languagePath}/docs${relativePath}/`).toString()})`;
|
|
});
|
|
}
|
|
|
|
module.exports = {
|
|
docsLinkRendererForLanguage,
|
|
renderPlaywrightDevLinks,
|
|
languageToRelativeDocsPath,
|
|
} |