chore: allow a script to generate release-notes for GitHub (#27596)

`node utils/render_release_notes.mjs js 1.39`
This commit is contained in:
Max Schmitt 2023-10-16 11:23:22 +02:00 committed by GitHub
parent b3bcf1c75a
commit 6b31b30df9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 268 additions and 111 deletions

View File

@ -10576,7 +10576,7 @@ export interface Locator {
* Returns an array of `node.innerText` values for all matching nodes.
*
* **NOTE** If you need to assert text on the page, prefer
* [locatorAssertions.toHaveText(expected[, options])](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-text)
* [expect(locator).toHaveText(expected[, options])](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-text)
* with `useInnerText` option to avoid flakiness. See [assertions guide](https://playwright.dev/docs/test-assertions) for more details.
*
* **Usage**
@ -10592,7 +10592,7 @@ export interface Locator {
* Returns an array of `node.textContent` values for all matching nodes.
*
* **NOTE** If you need to assert text on the page, prefer
* [locatorAssertions.toHaveText(expected[, options])](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-text)
* [expect(locator).toHaveText(expected[, options])](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-text)
* to avoid flakiness. See [assertions guide](https://playwright.dev/docs/test-assertions) for more details.
*
* **Usage**
@ -10898,7 +10898,7 @@ export interface Locator {
* Returns the number of elements matching the locator.
*
* **NOTE** If you need to assert the number of elements on the page, prefer
* [locatorAssertions.toHaveCount(count[, options])](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-count)
* [expect(locator).toHaveCount(count[, options])](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-count)
* to avoid flakiness. See [assertions guide](https://playwright.dev/docs/test-assertions) for more details.
*
* **Usage**
@ -11249,7 +11249,7 @@ export interface Locator {
* Returns the matching element's attribute value.
*
* **NOTE** If you need to assert an element's attribute, prefer
* [locatorAssertions.toHaveAttribute(name, value[, options])](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-attribute)
* [expect(locator).toHaveAttribute(name, value[, options])](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-attribute)
* to avoid flakiness. See [assertions guide](https://playwright.dev/docs/test-assertions) for more details.
* @param name Attribute name to get the value for.
* @param options
@ -11668,7 +11668,7 @@ export interface Locator {
* Returns the [`element.innerText`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/innerText).
*
* **NOTE** If you need to assert text on the page, prefer
* [locatorAssertions.toHaveText(expected[, options])](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-text)
* [expect(locator).toHaveText(expected[, options])](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-text)
* with `useInnerText` option to avoid flakiness. See [assertions guide](https://playwright.dev/docs/test-assertions) for more details.
* @param options
*/
@ -11686,7 +11686,7 @@ export interface Locator {
* Returns the value for the matching `<input>` or `<textarea>` or `<select>` element.
*
* **NOTE** If you need to assert input value, prefer
* [locatorAssertions.toHaveValue(value[, options])](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-value)
* [expect(locator).toHaveValue(value[, options])](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-value)
* to avoid flakiness. See [assertions guide](https://playwright.dev/docs/test-assertions) for more details.
*
* **Usage**
@ -11717,7 +11717,7 @@ export interface Locator {
* Returns whether the element is checked. Throws if the element is not a checkbox or radio input.
*
* **NOTE** If you need to assert that checkbox is checked, prefer
* [locatorAssertions.toBeChecked([options])](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-be-checked)
* [expect(locator).toBeChecked([options])](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-be-checked)
* to avoid flakiness. See [assertions guide](https://playwright.dev/docs/test-assertions) for more details.
*
* **Usage**
@ -11742,7 +11742,7 @@ export interface Locator {
* Returns whether the element is disabled, the opposite of [enabled](https://playwright.dev/docs/actionability#enabled).
*
* **NOTE** If you need to assert that an element is disabled, prefer
* [locatorAssertions.toBeDisabled([options])](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-be-disabled)
* [expect(locator).toBeDisabled([options])](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-be-disabled)
* to avoid flakiness. See [assertions guide](https://playwright.dev/docs/test-assertions) for more details.
*
* **Usage**
@ -11767,7 +11767,7 @@ export interface Locator {
* Returns whether the element is [editable](https://playwright.dev/docs/actionability#editable).
*
* **NOTE** If you need to assert that an element is editable, prefer
* [locatorAssertions.toBeEditable([options])](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-be-editable)
* [expect(locator).toBeEditable([options])](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-be-editable)
* to avoid flakiness. See [assertions guide](https://playwright.dev/docs/test-assertions) for more details.
*
* **Usage**
@ -11792,7 +11792,7 @@ export interface Locator {
* Returns whether the element is [enabled](https://playwright.dev/docs/actionability#enabled).
*
* **NOTE** If you need to assert that an element is enabled, prefer
* [locatorAssertions.toBeEnabled([options])](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-be-enabled)
* [expect(locator).toBeEnabled([options])](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-be-enabled)
* to avoid flakiness. See [assertions guide](https://playwright.dev/docs/test-assertions) for more details.
*
* **Usage**
@ -11817,7 +11817,7 @@ export interface Locator {
* Returns whether the element is hidden, the opposite of [visible](https://playwright.dev/docs/actionability#visible).
*
* **NOTE** If you need to assert that element is hidden, prefer
* [locatorAssertions.toBeHidden([options])](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-be-hidden)
* [expect(locator).toBeHidden([options])](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-be-hidden)
* to avoid flakiness. See [assertions guide](https://playwright.dev/docs/test-assertions) for more details.
*
* **Usage**
@ -11841,7 +11841,7 @@ export interface Locator {
* Returns whether the element is [visible](https://playwright.dev/docs/actionability#visible).
*
* **NOTE** If you need to assert that element is visible, prefer
* [locatorAssertions.toBeVisible([options])](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-be-visible)
* [expect(locator).toBeVisible([options])](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-be-visible)
* to avoid flakiness. See [assertions guide](https://playwright.dev/docs/test-assertions) for more details.
*
* **Usage**
@ -12445,7 +12445,7 @@ export interface Locator {
* Returns the [`node.textContent`](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent).
*
* **NOTE** If you need to assert text on the page, prefer
* [locatorAssertions.toHaveText(expected[, options])](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-text)
* [expect(locator).toHaveText(expected[, options])](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-text)
* to avoid flakiness. See [assertions guide](https://playwright.dev/docs/test-assertions) for more details.
* @param options
*/

View File

@ -623,7 +623,7 @@ interface TestConfig {
/**
* Configuration for the
* [pageAssertions.toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1)
* [expect(page).toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1)
* method.
*/
toHaveScreenshot?: {
@ -666,7 +666,7 @@ interface TestConfig {
/**
* Configuration for the
* [snapshotAssertions.toMatchSnapshot(name[, options])](https://playwright.dev/docs/api/class-snapshotassertions#snapshot-assertions-to-match-snapshot-1)
* [expect(value).toMatchSnapshot(name[, options])](https://playwright.dev/docs/api/class-snapshotassertions#snapshot-assertions-to-match-snapshot-1)
* method.
*/
toMatchSnapshot?: {
@ -1132,9 +1132,9 @@ interface TestConfig {
/**
* This option configures a template controlling location of snapshots generated by
* [pageAssertions.toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1)
* [expect(page).toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1)
* and
* [snapshotAssertions.toMatchSnapshot(name[, options])](https://playwright.dev/docs/api/class-snapshotassertions#snapshot-assertions-to-match-snapshot-1).
* [expect(value).toMatchSnapshot(name[, options])](https://playwright.dev/docs/api/class-snapshotassertions#snapshot-assertions-to-match-snapshot-1).
*
* **Usage**
*
@ -4594,7 +4594,7 @@ interface AsymmetricMatchers {
/**
* `expect.any()` matches any object instance created from the `constructor` or a corresponding primitive type. Use it
* inside
* [genericAssertions.toEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-equal)
* [expect(value).toEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-equal)
* to perform pattern matching.
*
* **Usage**
@ -4616,7 +4616,7 @@ interface AsymmetricMatchers {
any(sample: unknown): AsymmetricMatcher;
/**
* `expect.anything()` matches everything except `null` and `undefined`. Use it inside
* [genericAssertions.toEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-equal)
* [expect(value).toEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-equal)
* to perform pattern matching.
*
* **Usage**
@ -4634,7 +4634,7 @@ interface AsymmetricMatchers {
* Note that received array may be a superset of the expected array and contain some extra elements.
*
* Use this method inside
* [genericAssertions.toEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-equal)
* [expect(value).toEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-equal)
* to perform pattern matching.
*
* **Usage**
@ -4649,9 +4649,9 @@ interface AsymmetricMatchers {
arrayContaining(sample: Array<unknown>): AsymmetricMatcher;
/**
* Compares floating point numbers for approximate equality. Use this method inside
* [genericAssertions.toEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-equal)
* [expect(value).toEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-equal)
* to perform pattern matching. When just comparing two numbers, prefer
* [genericAssertions.toBeCloseTo(expected[, numDigits])](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-be-close-to).
* [expect(value).toBeCloseTo(expected[, numDigits])](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-be-close-to).
*
* **Usage**
*
@ -4669,7 +4669,7 @@ interface AsymmetricMatchers {
* object. Note that received object may be a superset of the expected object and contain some extra properties.
*
* Use this method inside
* [genericAssertions.toEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-equal)
* [expect(value).toEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-equal)
* to perform pattern matching. Object properties can be matchers to further relax the expectation. See examples.
*
* **Usage**
@ -4697,7 +4697,7 @@ interface AsymmetricMatchers {
objectContaining(sample: Record<string, unknown>): AsymmetricMatcher;
/**
* `expect.stringContaining()` matches a string that contains the expected substring. Use this method inside
* [genericAssertions.toEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-equal)
* [expect(value).toEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-equal)
* to perform pattern matching.
*
* **Usage**
@ -4712,7 +4712,7 @@ interface AsymmetricMatchers {
/**
* `expect.stringMatching()` matches a received string that in turn matches the expected pattern. Use this method
* inside
* [genericAssertions.toEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-equal)
* [expect(value).toEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-equal)
* to perform pattern matching.
*
* **Usage**
@ -4779,7 +4779,7 @@ interface GenericAssertions<R> {
toBe(expected: unknown): R;
/**
* Compares floating point numbers for approximate equality. Use this method instead of
* [genericAssertions.toBe(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-be)
* [expect(value).toBe(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-be)
* when comparing floating point numbers.
*
* **Usage**
@ -4967,10 +4967,10 @@ interface GenericAssertions<R> {
*
* For objects, this method recursively checks equality of all fields, rather than comparing objects by reference as
* performed by
* [genericAssertions.toContain(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-contain-2).
* [expect(value).toContain(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-contain-2).
*
* For primitive values, this method is equivalent to
* [genericAssertions.toContain(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-contain-2).
* [expect(value).toContain(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-contain-2).
*
* **Usage**
*
@ -4992,10 +4992,10 @@ interface GenericAssertions<R> {
*
* For objects, this method recursively checks equality of all fields, rather than comparing objects by reference as
* performed by
* [genericAssertions.toBe(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-be).
* [expect(value).toBe(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-be).
*
* For primitive values, this method is equivalent to
* [genericAssertions.toBe(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-be).
* [expect(value).toBe(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-be).
*
* **Usage**
*
@ -5006,29 +5006,29 @@ interface GenericAssertions<R> {
*
* **Non-strict equality**
*
* [genericAssertions.toEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-equal)
* [expect(value).toEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-equal)
* performs deep equality check that compares contents of the received and expected values. To ensure two objects
* reference the same instance, use
* [genericAssertions.toBe(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-be)
* [expect(value).toBe(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-be)
* instead.
*
* [genericAssertions.toEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-equal)
* [expect(value).toEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-equal)
* ignores `undefined` properties and array items, and does not insist on object types being equal. For stricter
* matching, use
* [genericAssertions.toStrictEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-strict-equal).
* [expect(value).toStrictEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-strict-equal).
*
* **Pattern matching**
*
* [genericAssertions.toEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-equal)
* [expect(value).toEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-equal)
* can be also used to perform pattern matching on objects, arrays and primitive types, with the help of the following
* matchers:
* - [genericAssertions.any(constructor)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-any)
* - [genericAssertions.anything()](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-anything)
* - [genericAssertions.arrayContaining(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-array-containing)
* - [genericAssertions.closeTo(expected[, numDigits])](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-close-to)
* - [genericAssertions.objectContaining(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-object-containing)
* - [genericAssertions.stringContaining(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-string-containing)
* - [genericAssertions.stringMatching(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-string-matching)
* - [expect(value).any(constructor)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-any)
* - [expect(value).anything()](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-anything)
* - [expect(value).arrayContaining(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-array-containing)
* - [expect(value).closeTo(expected[, numDigits])](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-close-to)
* - [expect(value).objectContaining(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-object-containing)
* - [expect(value).stringContaining(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-string-containing)
* - [expect(value).stringMatching(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-string-matching)
*
* Here is an example that asserts some of the values inside a complex object:
*
@ -5062,7 +5062,7 @@ interface GenericAssertions<R> {
/**
* Ensures that property at provided `keyPath` exists on the object and optionally checks that property is equal to
* the `expected`. Equality is checked recursively, similarly to
* [genericAssertions.toEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-equal).
* [expect(value).toEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-equal).
*
* **Usage**
*
@ -5101,7 +5101,7 @@ interface GenericAssertions<R> {
/**
* Compares contents of the value with contents of `expected`, performing "deep equality" check. Allows extra
* properties to be present in the value, unlike
* [genericAssertions.toEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-equal),
* [expect(value).toEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-equal),
* so you can check just a subset of object properties.
*
* When comparing arrays, the number of items must match, and each item is checked recursively.
@ -5127,7 +5127,7 @@ interface GenericAssertions<R> {
* Compares contents of the value with contents of `expected` **and** their types.
*
* Differences from
* [genericAssertions.toEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-equal):
* [expect(value).toEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-equal):
* - Keys with undefined properties are checked. For example, `{ a: undefined, b: 2 }` does not match `{ b: 2 }`.
* - Array sparseness is checked. For example, `[, 1]` does not match `[undefined, 1]`.
* - Object types are checked to be equal. For example, a class instance with fields `a` and `b` will not equal a
@ -5173,7 +5173,7 @@ interface GenericAssertions<R> {
toThrow(error?: unknown): R;
/**
* An alias for
* [genericAssertions.toThrow([expected])](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-throw).
* [expect(value).toThrow([expected])](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-throw).
*
* **Usage**
*
@ -6450,7 +6450,7 @@ interface PageAssertions {
interface SnapshotAssertions {
/**
* **NOTE** To compare screenshots, use
* [pageAssertions.toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1)
* [expect(page).toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1)
* instead.
*
* Ensures that passed value, either a [string] or a [Buffer], matches the expected snapshot stored in the test
@ -6504,7 +6504,7 @@ interface SnapshotAssertions {
/**
* **NOTE** To compare screenshots, use
* [pageAssertions.toHaveScreenshot([options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-2)
* [expect(page).toHaveScreenshot([options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-2)
* instead.
*
* Ensures that passed value, either a [string] or a [Buffer], matches the expected snapshot stored in the test
@ -6687,7 +6687,7 @@ interface TestProject {
/**
* Configuration for the
* [pageAssertions.toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1)
* [expect(page).toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1)
* method.
*/
toHaveScreenshot?: {
@ -6730,7 +6730,7 @@ interface TestProject {
/**
* Configuration for the
* [snapshotAssertions.toMatchSnapshot(name[, options])](https://playwright.dev/docs/api/class-snapshotassertions#snapshot-assertions-to-match-snapshot-1)
* [expect(value).toMatchSnapshot(name[, options])](https://playwright.dev/docs/api/class-snapshotassertions#snapshot-assertions-to-match-snapshot-1)
* method.
*/
toMatchSnapshot?: {
@ -6856,9 +6856,9 @@ interface TestProject {
/**
* This option configures a template controlling location of snapshots generated by
* [pageAssertions.toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1)
* [expect(page).toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1)
* and
* [snapshotAssertions.toMatchSnapshot(name[, options])](https://playwright.dev/docs/api/class-snapshotassertions#snapshot-assertions-to-match-snapshot-1).
* [expect(value).toMatchSnapshot(name[, options])](https://playwright.dev/docs/api/class-snapshotassertions#snapshot-assertions-to-match-snapshot-1).
*
* **Usage**
*

137
utils/doclint/linkUtils.js Normal file
View File

@ -0,0 +1,137 @@
/**
* 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.
*/
// @ts-check
const toKebabCase = require('lodash/kebabCase.js')
const createMarkdownLink = (languagePath, member, text) => {
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();
return `[${text}](https://playwright.dev${languagePath}/docs/api/class-${member.clazz.name.toLowerCase()}#${hash})`;
};
/**
* @param {string} language
* @returns {import('../doclint/documentation').Renderer}
*/
function docsLinkRendererForLanguage(language) {
const languagePath = languageToRelativeDocsPath(language);
return ({ clazz, member, param, option }) => {
if (param)
return `\`${param}\``;
if (option)
return `\`${option}\``;
if (clazz)
return `{@link ${clazz.name}}`;
if (!member || !member.clazz)
throw new Error('Internal error');
const className = member.clazz.varName === 'playwrightAssertions' ? '' : member.clazz.varName + '.';
if (member.kind === 'method')
return createMarkdownLink(languagePath, member, `${formatClassName(className, language)}${member.alias}(${renderJSSignature(member.argsArray)})`);
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 {import('../doclint/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,
}

View File

@ -25,6 +25,7 @@ const fs = require('fs');
const { parseOverrides } = require('./parseOverrides');
const exported = require('./exported.json');
const { parseApi } = require('../doclint/api_parser');
const { docsLinkRendererForLanguage, renderPlaywrightDevLinks } = require('../doclint/linkUtils');
Error.stackTraceLimit = 50;
@ -60,35 +61,7 @@ class TypesGenerator {
* @returns {Promise<string>}
*/
async generateTypes(overridesFile) {
const createMarkdownLink = (member, text) => {
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();
return `[${text}](https://playwright.dev/docs/api/class-${member.clazz.name.toLowerCase()}#${hash})`;
};
this.documentation.setLinkRenderer(item => {
const { clazz, member, param, option } = item;
if (param)
return `\`${param}\``;
if (option)
return `\`${option}\``;
if (clazz)
return `{@link ${clazz.name}}`;
if (!member || !member.clazz)
throw new Error('Internal error');
const className = member.clazz.varName === 'playwrightAssertions' ? '' : member.clazz.varName + '.';
if (member.kind === 'method')
return createMarkdownLink(member, `${className}${member.alias}(${this.renderJSSignature(member.argsArray)})`);
if (member.kind === 'event')
return createMarkdownLink(member, `${className}on('${member.alias.toLowerCase()}')`);
if (member.kind === 'property')
return createMarkdownLink(member, `${className}${member.alias}`);
throw new Error('Unknown member kind ' + member.kind);
});
this.documentation.setLinkRenderer(docsLinkRendererForLanguage('js'));
this.documentation.setCodeGroupsTransformer('js', tabs => tabs.filter(tab => tab.value === 'ts').map(tab => tab.spec));
this.documentation.generateSourceCodeComments();
@ -371,9 +344,7 @@ class TypesGenerator {
pushLine(line);
}
comment = out.join('\n');
comment = comment.replace(/\[([^\]]+)\]\((\.[^\)]+)\)/g, (match, p1, p2) => {
return `[${p1}](${new URL(p2.replace('.md', ''), 'https://playwright.dev/docs/api/').toString()})`;
});
comment = renderPlaywrightDevLinks(comment, '', '/api');
parts.push(indent + '/**');
parts.push(...comment.split('\n').map(line => indent + ' * ' + line.replace(/\*\//g, '*\\/')));
@ -489,33 +460,6 @@ class TypesGenerator {
return indent;
return this.writeComment(lines.join('\n'), indent) + '\n' + indent;
}
/**
* @param {docs.Member[]} args
*/
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('');
}
}
(async function () {

View File

@ -0,0 +1,76 @@
/**
* 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.
*/
// @ts-check
import path from 'path';
import fs from 'fs';
import { parseApi } from './doclint/api_parser.js';
import md, { visitAll } from './markdown.js';
import { renderPlaywrightDevLinks, docsLinkRendererForLanguage, languageToRelativeDocsPath } from './doclint/linkUtils.js';
const __dirname = new URL('.', import.meta.url).pathname;
const PROJECT_DIR = path.join(__dirname, '..');
const documentationRoot = path.join(PROJECT_DIR, 'docs', 'src');
const allowedLanguages = ['js', 'python', 'csharp', 'java'];
const [, , language, version] = process.argv;
if (!allowedLanguages.includes(language) || !version.match(/^\d+\.\d+$/))
throw new Error(`Usage: node ${path.basename(process.argv[1])} <language> <version>\n\nWhere <version> is a version tag without v prefix, e.g. 1.45`);
let documentation = parseApi(path.join(documentationRoot, 'api'));
if (language === 'js') {
documentation = documentation
.mergeWith(parseApi(path.join(documentationRoot, 'test-api'), path.join(documentationRoot, 'api', 'params.md')))
.mergeWith(parseApi(path.join(documentationRoot, 'test-reporter-api')));
}
documentation.setLinkRenderer(docsLinkRendererForLanguage(language));
const content = fs.readFileSync(path.join(documentationRoot, `release-notes-${language}.md`)).toString();
let nodes = md.parse(content);
documentation.renderLinksInNodes(nodes);
{
// Reduce by one heading level
visitAll(nodes, node => {
if (node.type === 'h4')
node.type = 'h3';
else if (node.type === 'h3')
node.type = 'h2';
else if (node.type === 'h2')
node.type = 'h1';
else if (node.type === 'h1')
node.type = 'h0';
});
}
// Find the version heading and use it as a starting point in the output.
{
let foundVersion = false;
visitAll(nodes, node => {
if (node.type === 'h1' && node.text === `Version ${version}`) {
nodes = node.children;
foundVersion = true;
}
});
if (!foundVersion)
throw new Error(`Could not find version ${version} in release notes.\nUsage: node ${path.basename(process.argv[1])} <language> <version>\n\nWhere <version> is a version tag without v prefix, e.g. 1.45`);
}
const output = renderPlaywrightDevLinks(md.render(nodes), languageToRelativeDocsPath(language), '');
process.stdout.write(output);