diff --git a/packages/playwright/types/test.d.ts b/packages/playwright/types/test.d.ts index 78f8eb7f4f440..a989fe69b29f4 100644 --- a/packages/playwright/types/test.d.ts +++ b/packages/playwright/types/test.d.ts @@ -1857,7 +1857,220 @@ export type TestDetails = { annotation?: TestDetailsAnnotation | TestDetailsAnnotation[]; } -interface SuiteFunction { +type TestBody = (args: TestArgs, testInfo: TestInfo) => Promise | void; +type ConditionBody = (args: TestArgs) => boolean; + +/** + * Playwright Test provides a `test` function to declare tests and `expect` function to write assertions. + * + * ```js + * import { test, expect } from '@playwright/test'; + * + * test('basic test', async ({ page }) => { + * await page.goto('https://playwright.dev/'); + * const name = await page.innerText('.navbar__title'); + * expect(name).toBe('Playwright'); + * }); + * ``` + * + */ +export interface TestType { + /** + * Declares a test. + * - `test(title, body)` + * - `test(title, details, body)` + * + * **Usage** + * + * ```js + * import { test, expect } from '@playwright/test'; + * + * test('basic test', async ({ page }) => { + * await page.goto('https://playwright.dev/'); + * // ... + * }); + * ``` + * + * **Tags** + * + * You can tag tests by providing additional test details. Alternatively, you can include tags in the test title. Note + * that each tag must start with `@` symbol. + * + * ```js + * import { test, expect } from '@playwright/test'; + * + * test('basic test', { + * tag: '@smoke', + * }, async ({ page }) => { + * await page.goto('https://playwright.dev/'); + * // ... + * }); + * + * test('another test @smoke', async ({ page }) => { + * await page.goto('https://playwright.dev/'); + * // ... + * }); + * ``` + * + * Test tags are displayed in the test report, and are available to a custom reporter via `TestCase.tags` property. + * + * You can also filter tests by their tags during test execution: + * - in the [command line](https://playwright.dev/docs/test-cli#reference); + * - in the config with [testConfig.grep](https://playwright.dev/docs/api/class-testconfig#test-config-grep) and + * [testProject.grep](https://playwright.dev/docs/api/class-testproject#test-project-grep); + * + * Learn more about [tagging](https://playwright.dev/docs/test-annotations#tag-tests). + * + * **Annotations** + * + * You can annotate tests by providing additional test details. + * + * ```js + * import { test, expect } from '@playwright/test'; + * + * test('basic test', { + * annotation: { + * type: 'issue', + * description: 'https://github.com/microsoft/playwright/issues/23180', + * }, + * }, async ({ page }) => { + * await page.goto('https://playwright.dev/'); + * // ... + * }); + * ``` + * + * Test annotations are displayed in the test report, and are available to a custom reporter via + * `TestCase.annotations` property. + * + * You can also add annotations during runtime by manipulating + * [testInfo.annotations](https://playwright.dev/docs/api/class-testinfo#test-info-annotations). + * + * Learn more about [test annotations](https://playwright.dev/docs/test-annotations). + * @param title Test title. + * @param details Additional test details. + * @param body Test body that takes one or two arguments: an object with fixtures and optional + * [TestInfo](https://playwright.dev/docs/api/class-testinfo). + */ + (title: string, body: TestBody): void; + /** + * Declares a test. + * - `test(title, body)` + * - `test(title, details, body)` + * + * **Usage** + * + * ```js + * import { test, expect } from '@playwright/test'; + * + * test('basic test', async ({ page }) => { + * await page.goto('https://playwright.dev/'); + * // ... + * }); + * ``` + * + * **Tags** + * + * You can tag tests by providing additional test details. Alternatively, you can include tags in the test title. Note + * that each tag must start with `@` symbol. + * + * ```js + * import { test, expect } from '@playwright/test'; + * + * test('basic test', { + * tag: '@smoke', + * }, async ({ page }) => { + * await page.goto('https://playwright.dev/'); + * // ... + * }); + * + * test('another test @smoke', async ({ page }) => { + * await page.goto('https://playwright.dev/'); + * // ... + * }); + * ``` + * + * Test tags are displayed in the test report, and are available to a custom reporter via `TestCase.tags` property. + * + * You can also filter tests by their tags during test execution: + * - in the [command line](https://playwright.dev/docs/test-cli#reference); + * - in the config with [testConfig.grep](https://playwright.dev/docs/api/class-testconfig#test-config-grep) and + * [testProject.grep](https://playwright.dev/docs/api/class-testproject#test-project-grep); + * + * Learn more about [tagging](https://playwright.dev/docs/test-annotations#tag-tests). + * + * **Annotations** + * + * You can annotate tests by providing additional test details. + * + * ```js + * import { test, expect } from '@playwright/test'; + * + * test('basic test', { + * annotation: { + * type: 'issue', + * description: 'https://github.com/microsoft/playwright/issues/23180', + * }, + * }, async ({ page }) => { + * await page.goto('https://playwright.dev/'); + * // ... + * }); + * ``` + * + * Test annotations are displayed in the test report, and are available to a custom reporter via + * `TestCase.annotations` property. + * + * You can also add annotations during runtime by manipulating + * [testInfo.annotations](https://playwright.dev/docs/api/class-testinfo#test-info-annotations). + * + * Learn more about [test annotations](https://playwright.dev/docs/test-annotations). + * @param title Test title. + * @param details Additional test details. + * @param body Test body that takes one or two arguments: an object with fixtures and optional + * [TestInfo](https://playwright.dev/docs/api/class-testinfo). + */ + (title: string, details: TestDetails, body: TestBody): void; + + /** + * Declares a focused test. If there are some focused tests or suites, all of them will be run but nothing else. + * - `test.only(title, body)` + * - `test.only(title, details, body)` + * + * **Usage** + * + * ```js + * test.only('focus this test', async ({ page }) => { + * // Run only focused tests in the entire project. + * }); + * ``` + * + * @param title Test title. + * @param details See [test.(call)(title[, details, body])](https://playwright.dev/docs/api/class-test#test-call) for test details + * description. + * @param body Test body that takes one or two arguments: an object with fixtures and optional + * [TestInfo](https://playwright.dev/docs/api/class-testinfo). + */ + only(title: string, body: TestBody): void; + /** + * Declares a focused test. If there are some focused tests or suites, all of them will be run but nothing else. + * - `test.only(title, body)` + * - `test.only(title, details, body)` + * + * **Usage** + * + * ```js + * test.only('focus this test', async ({ page }) => { + * // Run only focused tests in the entire project. + * }); + * ``` + * + * @param title Test title. + * @param details See [test.(call)(title[, details, body])](https://playwright.dev/docs/api/class-test#test-call) for test details + * description. + * @param body Test body that takes one or two arguments: an object with fixtures and optional + * [TestInfo](https://playwright.dev/docs/api/class-testinfo). + */ + only(title: string, details: TestDetails, body: TestBody): void; + /** * Declares a group of tests. * - `test.describe(title, callback)` @@ -1952,8 +2165,8 @@ interface SuiteFunction { * [test.describe([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe). Any tests * declared in this callback will belong to the group. */ - (title: string, callback: () => void): void; - /** + describe: { + /** * Declares a group of tests. * - `test.describe(title, callback)` * - `test.describe(callback)` @@ -2047,8 +2260,8 @@ interface SuiteFunction { * [test.describe([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe). Any tests * declared in this callback will belong to the group. */ - (callback: () => void): void; - /** + (title: string, callback: () => void): void; + /** * Declares a group of tests. * - `test.describe(title, callback)` * - `test.describe(callback)` @@ -2142,232 +2355,38 @@ interface SuiteFunction { * [test.describe([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe). Any tests * declared in this callback will belong to the group. */ - (title: string, details: TestDetails, callback: () => void): void; -} - -interface TestFunction { - /** - * Declares a test. - * - `test(title, body)` - * - `test(title, details, body)` + (callback: () => void): void; + /** + * Declares a group of tests. + * - `test.describe(title, callback)` + * - `test.describe(callback)` + * - `test.describe(title, details, callback)` * * **Usage** * + * You can declare a group of tests with a title. The title will be visible in the test report as a part of each + * test's title. + * * ```js - * import { test, expect } from '@playwright/test'; + * test.describe('two tests', () => { + * test('one', async ({ page }) => { + * // ... + * }); * - * test('basic test', async ({ page }) => { - * await page.goto('https://playwright.dev/'); - * // ... + * test('two', async ({ page }) => { + * // ... + * }); * }); * ``` * - * **Tags** + * **Anonymous group** * - * You can tag tests by providing additional test details. Alternatively, you can include tags in the test title. Note - * that each tag must start with `@` symbol. + * You can also declare a test group without a title. This is convenient to give a group of tests a common option with + * [test.use(options)](https://playwright.dev/docs/api/class-test#test-use). * * ```js - * import { test, expect } from '@playwright/test'; - * - * test('basic test', { - * tag: '@smoke', - * }, async ({ page }) => { - * await page.goto('https://playwright.dev/'); - * // ... - * }); - * - * test('another test @smoke', async ({ page }) => { - * await page.goto('https://playwright.dev/'); - * // ... - * }); - * ``` - * - * Test tags are displayed in the test report, and are available to a custom reporter via `TestCase.tags` property. - * - * You can also filter tests by their tags during test execution: - * - in the [command line](https://playwright.dev/docs/test-cli#reference); - * - in the config with [testConfig.grep](https://playwright.dev/docs/api/class-testconfig#test-config-grep) and - * [testProject.grep](https://playwright.dev/docs/api/class-testproject#test-project-grep); - * - * Learn more about [tagging](https://playwright.dev/docs/test-annotations#tag-tests). - * - * **Annotations** - * - * You can annotate tests by providing additional test details. - * - * ```js - * import { test, expect } from '@playwright/test'; - * - * test('basic test', { - * annotation: { - * type: 'issue', - * description: 'https://github.com/microsoft/playwright/issues/23180', - * }, - * }, async ({ page }) => { - * await page.goto('https://playwright.dev/'); - * // ... - * }); - * ``` - * - * Test annotations are displayed in the test report, and are available to a custom reporter via - * `TestCase.annotations` property. - * - * You can also add annotations during runtime by manipulating - * [testInfo.annotations](https://playwright.dev/docs/api/class-testinfo#test-info-annotations). - * - * Learn more about [test annotations](https://playwright.dev/docs/test-annotations). - * @param title Test title. - * @param details Additional test details. - * @param body Test body that takes one or two arguments: an object with fixtures and optional - * [TestInfo](https://playwright.dev/docs/api/class-testinfo). - */ - (title: string, body: (args: TestArgs, testInfo: TestInfo) => Promise | void): void; - /** - * Declares a test. - * - `test(title, body)` - * - `test(title, details, body)` - * - * **Usage** - * - * ```js - * import { test, expect } from '@playwright/test'; - * - * test('basic test', async ({ page }) => { - * await page.goto('https://playwright.dev/'); - * // ... - * }); - * ``` - * - * **Tags** - * - * You can tag tests by providing additional test details. Alternatively, you can include tags in the test title. Note - * that each tag must start with `@` symbol. - * - * ```js - * import { test, expect } from '@playwright/test'; - * - * test('basic test', { - * tag: '@smoke', - * }, async ({ page }) => { - * await page.goto('https://playwright.dev/'); - * // ... - * }); - * - * test('another test @smoke', async ({ page }) => { - * await page.goto('https://playwright.dev/'); - * // ... - * }); - * ``` - * - * Test tags are displayed in the test report, and are available to a custom reporter via `TestCase.tags` property. - * - * You can also filter tests by their tags during test execution: - * - in the [command line](https://playwright.dev/docs/test-cli#reference); - * - in the config with [testConfig.grep](https://playwright.dev/docs/api/class-testconfig#test-config-grep) and - * [testProject.grep](https://playwright.dev/docs/api/class-testproject#test-project-grep); - * - * Learn more about [tagging](https://playwright.dev/docs/test-annotations#tag-tests). - * - * **Annotations** - * - * You can annotate tests by providing additional test details. - * - * ```js - * import { test, expect } from '@playwright/test'; - * - * test('basic test', { - * annotation: { - * type: 'issue', - * description: 'https://github.com/microsoft/playwright/issues/23180', - * }, - * }, async ({ page }) => { - * await page.goto('https://playwright.dev/'); - * // ... - * }); - * ``` - * - * Test annotations are displayed in the test report, and are available to a custom reporter via - * `TestCase.annotations` property. - * - * You can also add annotations during runtime by manipulating - * [testInfo.annotations](https://playwright.dev/docs/api/class-testinfo#test-info-annotations). - * - * Learn more about [test annotations](https://playwright.dev/docs/test-annotations). - * @param title Test title. - * @param details Additional test details. - * @param body Test body that takes one or two arguments: an object with fixtures and optional - * [TestInfo](https://playwright.dev/docs/api/class-testinfo). - */ - (title: string, details: TestDetails, body: (args: TestArgs, testInfo: TestInfo) => Promise | void): void; -} - -/** - * Playwright Test provides a `test` function to declare tests and `expect` function to write assertions. - * - * ```js - * import { test, expect } from '@playwright/test'; - * - * test('basic test', async ({ page }) => { - * await page.goto('https://playwright.dev/'); - * const name = await page.innerText('.navbar__title'); - * expect(name).toBe('Playwright'); - * }); - * ``` - * - */ -export interface TestType extends TestFunction { - /** - * Declares a focused test. If there are some focused tests or suites, all of them will be run but nothing else. - * - `test.only(title, body)` - * - `test.only(title, details, body)` - * - * **Usage** - * - * ```js - * test.only('focus this test', async ({ page }) => { - * // Run only focused tests in the entire project. - * }); - * ``` - * - * @param title Test title. - * @param details See [test.(call)(title[, details, body])](https://playwright.dev/docs/api/class-test#test-call) for test details - * description. - * @param body Test body that takes one or two arguments: an object with fixtures and optional - * [TestInfo](https://playwright.dev/docs/api/class-testinfo). - */ - only: TestFunction; - /** - * Declares a group of tests. - * - `test.describe(title, callback)` - * - `test.describe(callback)` - * - `test.describe(title, details, callback)` - * - * **Usage** - * - * You can declare a group of tests with a title. The title will be visible in the test report as a part of each - * test's title. - * - * ```js - * test.describe('two tests', () => { - * test('one', async ({ page }) => { - * // ... - * }); - * - * test('two', async ({ page }) => { - * // ... - * }); - * }); - * ``` - * - * **Anonymous group** - * - * You can also declare a test group without a title. This is convenient to give a group of tests a common option with - * [test.use(options)](https://playwright.dev/docs/api/class-test#test-use). - * - * ```js - * test.describe(() => { - * test.use({ colorScheme: 'dark' }); + * test.describe(() => { + * test.use({ colorScheme: 'dark' }); * * test('one', async ({ page }) => { * // ... @@ -2431,7 +2450,44 @@ export interface TestType void): void; + + /** + * Declares a focused group of tests. If there are some focused tests or suites, all of them will be run but nothing + * else. + * - `test.describe.only(title, callback)` + * - `test.describe.only(callback)` + * - `test.describe.only(title, details, callback)` + * + * **Usage** + * + * ```js + * test.describe.only('focused group', () => { + * test('in the focused group', async ({ page }) => { + * // This test will run + * }); + * }); + * test('not in the focused group', async ({ page }) => { + * // This test will not run + * }); + * ``` + * + * You can also omit the title. + * + * ```js + * test.describe.only(() => { + * // ... + * }); + * ``` + * + * @param title Group title. + * @param details See [test.describe([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe) for + * details description. + * @param callback A callback that is run immediately when calling + * [test.describe.only([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe-only). + * Any tests added in this callback will belong to the group. + */ + only(title: string, callback: () => void): void; /** * Declares a focused group of tests. If there are some focused tests or suites, all of them will be run but nothing * else. @@ -2446,16 +2502,500 @@ export interface TestType { * // This test will run * }); - * }); - * test('not in the focused group', async ({ page }) => { - * // This test will not run + * }); + * test('not in the focused group', async ({ page }) => { + * // This test will not run + * }); + * ``` + * + * You can also omit the title. + * + * ```js + * test.describe.only(() => { + * // ... + * }); + * ``` + * + * @param title Group title. + * @param details See [test.describe([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe) for + * details description. + * @param callback A callback that is run immediately when calling + * [test.describe.only([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe-only). + * Any tests added in this callback will belong to the group. + */ + only(callback: () => void): void; + /** + * Declares a focused group of tests. If there are some focused tests or suites, all of them will be run but nothing + * else. + * - `test.describe.only(title, callback)` + * - `test.describe.only(callback)` + * - `test.describe.only(title, details, callback)` + * + * **Usage** + * + * ```js + * test.describe.only('focused group', () => { + * test('in the focused group', async ({ page }) => { + * // This test will run + * }); + * }); + * test('not in the focused group', async ({ page }) => { + * // This test will not run + * }); + * ``` + * + * You can also omit the title. + * + * ```js + * test.describe.only(() => { + * // ... + * }); + * ``` + * + * @param title Group title. + * @param details See [test.describe([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe) for + * details description. + * @param callback A callback that is run immediately when calling + * [test.describe.only([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe-only). + * Any tests added in this callback will belong to the group. + */ + only(title: string, details: TestDetails, callback: () => void): void; + + /** + * Declares a skipped test group, similarly to + * [test.describe([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe). Tests in the + * skipped group are never run. + * - `test.describe.skip(title, callback)` + * - `test.describe.skip(title)` + * - `test.describe.skip(title, details, callback)` + * + * **Usage** + * + * ```js + * test.describe.skip('skipped group', () => { + * test('example', async ({ page }) => { + * // This test will not run + * }); + * }); + * ``` + * + * You can also omit the title. + * + * ```js + * test.describe.skip(() => { + * // ... + * }); + * ``` + * + * @param title Group title. + * @param details See [test.describe([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe) for + * details description. + * @param callback A callback that is run immediately when calling + * [test.describe.skip(title[, details, callback])](https://playwright.dev/docs/api/class-test#test-describe-skip). + * Any tests added in this callback will belong to the group, and will not be run. + */ + skip(title: string, callback: () => void): void; + /** + * Declares a skipped test group, similarly to + * [test.describe([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe). Tests in the + * skipped group are never run. + * - `test.describe.skip(title, callback)` + * - `test.describe.skip(title)` + * - `test.describe.skip(title, details, callback)` + * + * **Usage** + * + * ```js + * test.describe.skip('skipped group', () => { + * test('example', async ({ page }) => { + * // This test will not run + * }); + * }); + * ``` + * + * You can also omit the title. + * + * ```js + * test.describe.skip(() => { + * // ... + * }); + * ``` + * + * @param title Group title. + * @param details See [test.describe([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe) for + * details description. + * @param callback A callback that is run immediately when calling + * [test.describe.skip(title[, details, callback])](https://playwright.dev/docs/api/class-test#test-describe-skip). + * Any tests added in this callback will belong to the group, and will not be run. + */ + skip(callback: () => void): void; + /** + * Declares a skipped test group, similarly to + * [test.describe([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe). Tests in the + * skipped group are never run. + * - `test.describe.skip(title, callback)` + * - `test.describe.skip(title)` + * - `test.describe.skip(title, details, callback)` + * + * **Usage** + * + * ```js + * test.describe.skip('skipped group', () => { + * test('example', async ({ page }) => { + * // This test will not run + * }); + * }); + * ``` + * + * You can also omit the title. + * + * ```js + * test.describe.skip(() => { + * // ... + * }); + * ``` + * + * @param title Group title. + * @param details See [test.describe([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe) for + * details description. + * @param callback A callback that is run immediately when calling + * [test.describe.skip(title[, details, callback])](https://playwright.dev/docs/api/class-test#test-describe-skip). + * Any tests added in this callback will belong to the group, and will not be run. + */ + skip(title: string, details: TestDetails, callback: () => void): void; + + /** + * Declares a test group similarly to + * [test.describe([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe). Tests in + * this group are marked as "fixme" and will not be executed. + * - `test.describe.fixme(title, callback)` + * - `test.describe.fixme(callback)` + * - `test.describe.fixme(title, details, callback)` + * + * **Usage** + * + * ```js + * test.describe.fixme('broken tests that should be fixed', () => { + * test('example', async ({ page }) => { + * // This test will not run + * }); + * }); + * ``` + * + * You can also omit the title. + * + * ```js + * test.describe.fixme(() => { + * // ... + * }); + * ``` + * + * @param title Group title. + * @param details See [test.describe([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe) for + * details description. + * @param callback A callback that is run immediately when calling + * [test.describe.fixme([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe-fixme). + * Any tests added in this callback will belong to the group, and will not be run. + */ + fixme(title: string, callback: () => void): void; + /** + * Declares a test group similarly to + * [test.describe([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe). Tests in + * this group are marked as "fixme" and will not be executed. + * - `test.describe.fixme(title, callback)` + * - `test.describe.fixme(callback)` + * - `test.describe.fixme(title, details, callback)` + * + * **Usage** + * + * ```js + * test.describe.fixme('broken tests that should be fixed', () => { + * test('example', async ({ page }) => { + * // This test will not run + * }); + * }); + * ``` + * + * You can also omit the title. + * + * ```js + * test.describe.fixme(() => { + * // ... + * }); + * ``` + * + * @param title Group title. + * @param details See [test.describe([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe) for + * details description. + * @param callback A callback that is run immediately when calling + * [test.describe.fixme([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe-fixme). + * Any tests added in this callback will belong to the group, and will not be run. + */ + fixme(callback: () => void): void; + /** + * Declares a test group similarly to + * [test.describe([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe). Tests in + * this group are marked as "fixme" and will not be executed. + * - `test.describe.fixme(title, callback)` + * - `test.describe.fixme(callback)` + * - `test.describe.fixme(title, details, callback)` + * + * **Usage** + * + * ```js + * test.describe.fixme('broken tests that should be fixed', () => { + * test('example', async ({ page }) => { + * // This test will not run + * }); + * }); + * ``` + * + * You can also omit the title. + * + * ```js + * test.describe.fixme(() => { + * // ... + * }); + * ``` + * + * @param title Group title. + * @param details See [test.describe([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe) for + * details description. + * @param callback A callback that is run immediately when calling + * [test.describe.fixme([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe-fixme). + * Any tests added in this callback will belong to the group, and will not be run. + */ + fixme(title: string, details: TestDetails, callback: () => void): void; + + /** + * **NOTE** See [test.describe.configure([options])](https://playwright.dev/docs/api/class-test#test-describe-configure) for + * the preferred way of configuring the execution mode. + * + * Declares a group of tests that should always be run serially. If one of the tests fails, all subsequent tests are + * skipped. All tests in a group are retried together. + * + * **NOTE** Using serial is not recommended. It is usually better to make your tests isolated, so they can be run + * independently. + * + * - `test.describe.serial(title, callback)` + * - `test.describe.serial(title)` + * - `test.describe.serial(title, details, callback)` + * + * **Usage** + * + * ```js + * test.describe.serial('group', () => { + * test('runs first', async ({ page }) => {}); + * test('runs second', async ({ page }) => {}); + * }); + * ``` + * + * You can also omit the title. + * + * ```js + * test.describe.serial(() => { + * // ... + * }); + * ``` + * + * @param title Group title. + * @param details See [test.describe([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe) for + * details description. + * @param callback A callback that is run immediately when calling + * [test.describe.serial([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe-serial). + * Any tests added in this callback will belong to the group. + */ + serial: { + /** + * **NOTE** See [test.describe.configure([options])](https://playwright.dev/docs/api/class-test#test-describe-configure) for + * the preferred way of configuring the execution mode. + * + * Declares a group of tests that should always be run serially. If one of the tests fails, all subsequent tests are + * skipped. All tests in a group are retried together. + * + * **NOTE** Using serial is not recommended. It is usually better to make your tests isolated, so they can be run + * independently. + * + * - `test.describe.serial(title, callback)` + * - `test.describe.serial(title)` + * - `test.describe.serial(title, details, callback)` + * + * **Usage** + * + * ```js + * test.describe.serial('group', () => { + * test('runs first', async ({ page }) => {}); + * test('runs second', async ({ page }) => {}); + * }); + * ``` + * + * You can also omit the title. + * + * ```js + * test.describe.serial(() => { + * // ... + * }); + * ``` + * + * @param title Group title. + * @param details See [test.describe([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe) for + * details description. + * @param callback A callback that is run immediately when calling + * [test.describe.serial([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe-serial). + * Any tests added in this callback will belong to the group. + */ + (title: string, callback: () => void): void; + /** + * **NOTE** See [test.describe.configure([options])](https://playwright.dev/docs/api/class-test#test-describe-configure) for + * the preferred way of configuring the execution mode. + * + * Declares a group of tests that should always be run serially. If one of the tests fails, all subsequent tests are + * skipped. All tests in a group are retried together. + * + * **NOTE** Using serial is not recommended. It is usually better to make your tests isolated, so they can be run + * independently. + * + * - `test.describe.serial(title, callback)` + * - `test.describe.serial(title)` + * - `test.describe.serial(title, details, callback)` + * + * **Usage** + * + * ```js + * test.describe.serial('group', () => { + * test('runs first', async ({ page }) => {}); + * test('runs second', async ({ page }) => {}); + * }); + * ``` + * + * You can also omit the title. + * + * ```js + * test.describe.serial(() => { + * // ... + * }); + * ``` + * + * @param title Group title. + * @param details See [test.describe([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe) for + * details description. + * @param callback A callback that is run immediately when calling + * [test.describe.serial([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe-serial). + * Any tests added in this callback will belong to the group. + */ + (callback: () => void): void; + /** + * **NOTE** See [test.describe.configure([options])](https://playwright.dev/docs/api/class-test#test-describe-configure) for + * the preferred way of configuring the execution mode. + * + * Declares a group of tests that should always be run serially. If one of the tests fails, all subsequent tests are + * skipped. All tests in a group are retried together. + * + * **NOTE** Using serial is not recommended. It is usually better to make your tests isolated, so they can be run + * independently. + * + * - `test.describe.serial(title, callback)` + * - `test.describe.serial(title)` + * - `test.describe.serial(title, details, callback)` + * + * **Usage** + * + * ```js + * test.describe.serial('group', () => { + * test('runs first', async ({ page }) => {}); + * test('runs second', async ({ page }) => {}); + * }); + * ``` + * + * You can also omit the title. + * + * ```js + * test.describe.serial(() => { + * // ... + * }); + * ``` + * + * @param title Group title. + * @param details See [test.describe([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe) for + * details description. + * @param callback A callback that is run immediately when calling + * [test.describe.serial([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe-serial). + * Any tests added in this callback will belong to the group. + */ + (title: string, details: TestDetails, callback: () => void): void; + + /** + * **NOTE** See [test.describe.configure([options])](https://playwright.dev/docs/api/class-test#test-describe-configure) for + * the preferred way of configuring the execution mode. + * + * Declares a focused group of tests that should always be run serially. If one of the tests fails, all subsequent + * tests are skipped. All tests in a group are retried together. If there are some focused tests or suites, all of + * them will be run but nothing else. + * + * **NOTE** Using serial is not recommended. It is usually better to make your tests isolated, so they can be run + * independently. + * + * - `test.describe.serial.only(title, callback)` + * - `test.describe.serial.only(title)` + * - `test.describe.serial.only(title, details, callback)` + * + * **Usage** + * + * ```js + * test.describe.serial.only('group', () => { + * test('runs first', async ({ page }) => { + * }); + * test('runs second', async ({ page }) => { + * }); + * }); + * ``` + * + * You can also omit the title. + * + * ```js + * test.describe.serial.only(() => { + * // ... + * }); + * ``` + * + * @param title Group title. + * @param details See [test.describe([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe) for + * details description. + * @param callback A callback that is run immediately when calling + * [test.describe.serial.only(title[, details, callback])](https://playwright.dev/docs/api/class-test#test-describe-serial-only). + * Any tests added in this callback will belong to the group. + */ + only(title: string, callback: () => void): void; + /** + * **NOTE** See [test.describe.configure([options])](https://playwright.dev/docs/api/class-test#test-describe-configure) for + * the preferred way of configuring the execution mode. + * + * Declares a focused group of tests that should always be run serially. If one of the tests fails, all subsequent + * tests are skipped. All tests in a group are retried together. If there are some focused tests or suites, all of + * them will be run but nothing else. + * + * **NOTE** Using serial is not recommended. It is usually better to make your tests isolated, so they can be run + * independently. + * + * - `test.describe.serial.only(title, callback)` + * - `test.describe.serial.only(title)` + * - `test.describe.serial.only(title, details, callback)` + * + * **Usage** + * + * ```js + * test.describe.serial.only('group', () => { + * test('runs first', async ({ page }) => { + * }); + * test('runs second', async ({ page }) => { + * }); * }); * ``` * * You can also omit the title. * * ```js - * test.describe.only(() => { + * test.describe.serial.only(() => { * // ... * }); * ``` @@ -2464,24 +3004,32 @@ export interface TestType void): void; + /** + * **NOTE** See [test.describe.configure([options])](https://playwright.dev/docs/api/class-test#test-describe-configure) for + * the preferred way of configuring the execution mode. + * + * Declares a focused group of tests that should always be run serially. If one of the tests fails, all subsequent + * tests are skipped. All tests in a group are retried together. If there are some focused tests or suites, all of + * them will be run but nothing else. + * + * **NOTE** Using serial is not recommended. It is usually better to make your tests isolated, so they can be run + * independently. + * + * - `test.describe.serial.only(title, callback)` + * - `test.describe.serial.only(title)` + * - `test.describe.serial.only(title, details, callback)` * * **Usage** * * ```js - * test.describe.skip('skipped group', () => { - * test('example', async ({ page }) => { - * // This test will not run + * test.describe.serial.only('group', () => { + * test('runs first', async ({ page }) => { + * }); + * test('runs second', async ({ page }) => { * }); * }); * ``` @@ -2489,7 +3037,7 @@ export interface TestType { + * test.describe.serial.only(() => { * // ... * }); * ``` @@ -2498,32 +3046,40 @@ export interface TestType void): void; + }; + /** - * Declares a test group similarly to - * [test.describe([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe). Tests in - * this group are marked as "fixme" and will not be executed. - * - `test.describe.fixme(title, callback)` - * - `test.describe.fixme(callback)` - * - `test.describe.fixme(title, details, callback)` + * **NOTE** See [test.describe.configure([options])](https://playwright.dev/docs/api/class-test#test-describe-configure) for + * the preferred way of configuring the execution mode. + * + * Declares a group of tests that could be run in parallel. By default, tests in a single test file run one after + * another, but using + * [test.describe.parallel([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe-parallel) + * allows them to run in parallel. + * - `test.describe.parallel(title, callback)` + * - `test.describe.parallel(callback)` + * - `test.describe.parallel(title, details, callback)` * * **Usage** * * ```js - * test.describe.fixme('broken tests that should be fixed', () => { - * test('example', async ({ page }) => { - * // This test will not run - * }); + * test.describe.parallel('group', () => { + * test('runs in parallel 1', async ({ page }) => {}); + * test('runs in parallel 2', async ({ page }) => {}); * }); * ``` * + * Note that parallel tests are executed in separate processes and cannot share any state or global variables. Each of + * the parallel tests executes all relevant hooks. + * * You can also omit the title. * * ```js - * test.describe.fixme(() => { + * test.describe.parallel(() => { * // ... * }); * ``` @@ -2532,37 +3088,38 @@ export interface TestType { - * test('runs first', async ({ page }) => {}); - * test('runs second', async ({ page }) => {}); + * test.describe.parallel('group', () => { + * test('runs in parallel 1', async ({ page }) => {}); + * test('runs in parallel 2', async ({ page }) => {}); * }); * ``` * + * Note that parallel tests are executed in separate processes and cannot share any state or global variables. Each of + * the parallel tests executes all relevant hooks. + * * You can also omit the title. * * ```js - * test.describe.serial(() => { + * test.describe.parallel(() => { * // ... * }); * ``` @@ -2571,40 +3128,38 @@ export interface TestType void): void; /** * **NOTE** See [test.describe.configure([options])](https://playwright.dev/docs/api/class-test#test-describe-configure) for * the preferred way of configuring the execution mode. * - * Declares a focused group of tests that should always be run serially. If one of the tests fails, all subsequent - * tests are skipped. All tests in a group are retried together. If there are some focused tests or suites, all of - * them will be run but nothing else. - * - * **NOTE** Using serial is not recommended. It is usually better to make your tests isolated, so they can be run - * independently. - * - * - `test.describe.serial.only(title, callback)` - * - `test.describe.serial.only(title)` - * - `test.describe.serial.only(title, details, callback)` + * Declares a group of tests that could be run in parallel. By default, tests in a single test file run one after + * another, but using + * [test.describe.parallel([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe-parallel) + * allows them to run in parallel. + * - `test.describe.parallel(title, callback)` + * - `test.describe.parallel(callback)` + * - `test.describe.parallel(title, details, callback)` * * **Usage** * * ```js - * test.describe.serial.only('group', () => { - * test('runs first', async ({ page }) => { - * }); - * test('runs second', async ({ page }) => { - * }); + * test.describe.parallel('group', () => { + * test('runs in parallel 1', async ({ page }) => {}); + * test('runs in parallel 2', async ({ page }) => {}); * }); * ``` * + * Note that parallel tests are executed in separate processes and cannot share any state or global variables. Each of + * the parallel tests executes all relevant hooks. + * * You can also omit the title. * * ```js - * test.describe.serial.only(() => { + * test.describe.parallel(() => { * // ... * }); * ``` @@ -2613,12 +3168,11 @@ export interface TestType void): void; + /** * **NOTE** See [test.describe.configure([options])](https://playwright.dev/docs/api/class-test#test-describe-configure) for * the preferred way of configuring the execution mode. * @@ -2657,7 +3211,80 @@ export interface TestType void): void; + + /** + * **NOTE** See [test.describe.configure([options])](https://playwright.dev/docs/api/class-test#test-describe-configure) for + * the preferred way of configuring the execution mode. + * + * Declares a focused group of tests that could be run in parallel. This is similar to + * [test.describe.parallel([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe-parallel), + * but focuses the group. If there are some focused tests or suites, all of them will be run but nothing else. + * - `test.describe.parallel.only(title, callback)` + * - `test.describe.parallel.only(callback)` + * - `test.describe.parallel.only(title, details, callback)` + * + * **Usage** + * + * ```js + * test.describe.parallel.only('group', () => { + * test('runs in parallel 1', async ({ page }) => {}); + * test('runs in parallel 2', async ({ page }) => {}); + * }); + * ``` + * + * You can also omit the title. + * + * ```js + * test.describe.parallel.only(() => { + * // ... + * }); + * ``` + * + * @param title Group title. + * @param details See [test.describe([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe) for + * details description. + * @param callback A callback that is run immediately when calling + * [test.describe.parallel.only([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe-parallel-only). + * Any tests added in this callback will belong to the group. + */ + only(title: string, callback: () => void): void; + /** + * **NOTE** See [test.describe.configure([options])](https://playwright.dev/docs/api/class-test#test-describe-configure) for + * the preferred way of configuring the execution mode. + * + * Declares a focused group of tests that could be run in parallel. This is similar to + * [test.describe.parallel([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe-parallel), + * but focuses the group. If there are some focused tests or suites, all of them will be run but nothing else. + * - `test.describe.parallel.only(title, callback)` + * - `test.describe.parallel.only(callback)` + * - `test.describe.parallel.only(title, details, callback)` + * + * **Usage** + * + * ```js + * test.describe.parallel.only('group', () => { + * test('runs in parallel 1', async ({ page }) => {}); + * test('runs in parallel 2', async ({ page }) => {}); + * }); + * ``` + * + * You can also omit the title. + * + * ```js + * test.describe.parallel.only(() => { + * // ... + * }); + * ``` + * + * @param title Group title. + * @param details See [test.describe([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe) for + * details description. + * @param callback A callback that is run immediately when calling + * [test.describe.parallel.only([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe-parallel-only). + * Any tests added in this callback will belong to the group. + */ + only(callback: () => void): void; /** * **NOTE** See [test.describe.configure([options])](https://playwright.dev/docs/api/class-test#test-describe-configure) for * the preferred way of configuring the execution mode. @@ -2693,8 +3320,9 @@ export interface TestType void): void; }; + /** * Configures the enclosing scope. Can be executed either on the top level or inside a describe. Configuration applies * to the entire scope, regardless of whether it run before or after the test declaration. @@ -2754,6 +3382,7 @@ export interface TestType void; }; + /** * Skip a test. Playwright will not run the test past the `test.skip()` call. * @@ -2834,7 +3463,7 @@ export interface TestType Promise | void): void; + skip(title: string, body: TestBody): void; /** * Skip a test. Playwright will not run the test past the `test.skip()` call. * @@ -2915,7 +3544,7 @@ export interface TestType Promise | void): void; + skip(title: string, details: TestDetails, body: TestBody): void; /** * Skip a test. Playwright will not run the test past the `test.skip()` call. * @@ -3158,7 +3787,8 @@ export interface TestType boolean, description?: string): void; + skip(callback: ConditionBody, description?: string): void; + /** * Mark a test as "fixme", with the intention to fix it. Playwright will not run the test past the `test.fixme()` * call. @@ -3236,7 +3866,7 @@ export interface TestType Promise | void): void; + fixme(title: string, body: TestBody): void; /** * Mark a test as "fixme", with the intention to fix it. Playwright will not run the test past the `test.fixme()` * call. @@ -3314,7 +3944,7 @@ export interface TestType Promise | void): void; + fixme(title: string, details: TestDetails, body: TestBody): void; /** * Mark a test as "fixme", with the intention to fix it. Playwright will not run the test past the `test.fixme()` * call. @@ -3548,7 +4178,8 @@ export interface TestType boolean, description?: string): void; + fixme(callback: ConditionBody, description?: string): void; + /** * Marks a test as "should fail". Playwright runs this test and ensures that it is actually failing. This is useful * for documentation purposes to acknowledge that some functionality is broken until it is fixed. @@ -3702,7 +4333,7 @@ export interface TestType Promise | void): void; + (title: string, body: TestBody): void; /** * Marks a test as "should fail". Playwright runs this test and ensures that it is actually failing. This is useful * for documentation purposes to acknowledge that some functionality is broken until it is fixed. @@ -3779,7 +4410,7 @@ export interface TestType Promise | void): void; + (title: string, details: TestDetails, body: TestBody): void; /** * Marks a test as "should fail". Playwright runs this test and ensures that it is actually failing. This is useful * for documentation purposes to acknowledge that some functionality is broken until it is fixed. @@ -3933,7 +4564,7 @@ export interface TestType boolean, description?: string): void; + (callback: ConditionBody, description?: string): void; /** * Marks a test as "should fail". Playwright runs this test and ensures that it is actually failing. This is useful * for documentation purposes to acknowledge that some functionality is broken until it is fixed. @@ -4011,6 +4642,37 @@ export interface TestType { + * // This test is expected to fail + * }); + * test('not in the focused group', async ({ page }) => { + * // This test will not run + * }); + * ``` + * + * @param title Test title. + * @param details See [test.describe([title, details, callback])](https://playwright.dev/docs/api/class-test#test-describe) for test + * details description. + * @param body Test body that takes one or two arguments: an object with fixtures and optional + * [TestInfo](https://playwright.dev/docs/api/class-testinfo). + */ + only(title: string, body: TestBody): void; /** * You can use `test.fail.only` to focus on a specific test that is expected to fail. This is particularly useful when * debugging a failing test or working on a specific issue. @@ -4040,8 +4702,9 @@ export interface TestType; + only(title: string, details: TestDetails, body: TestBody): void; } + /** * Marks a test as "slow". Slow test will be given triple the default timeout. * @@ -4215,7 +4878,8 @@ export interface TestType boolean, description?: string): void; + slow(callback: ConditionBody, description?: string): void; + /** * Changes the timeout for the test. Zero means no timeout. Learn more about [various timeouts](https://playwright.dev/docs/test-timeouts). * diff --git a/utils/generate_types/index.js b/utils/generate_types/index.js index ae988ac32c168..b3ad1c4f23ce7 100644 --- a/utils/generate_types/index.js +++ b/utils/generate_types/index.js @@ -93,25 +93,8 @@ class TypesGenerator { handledClasses.add(className); return this.writeComment(docClass.comment, '') + '\n'; }, (className, methodName, overloadIndex) => { - if (className === 'SuiteFunction' && methodName === '__call') { - const cls = this.documentation.classes.get('Test'); - if (!cls) - throw new Error(`Unknown class "Test"`); - const method = cls.membersArray.find(m => m.alias === 'describe'); - if (!method) - throw new Error(`Unknown method "Test.describe"`); - return this.memberJSDOC(method, ' ').trimLeft(); - } - if (className === 'TestFunction' && methodName === '__call') { - const cls = this.documentation.classes.get('Test'); - if (!cls) - throw new Error(`Unknown class "Test"`); - const method = cls.membersArray.find(m => m.alias === '(call)'); - if (!method) - throw new Error(`Unknown method "Test.(call)"`); - return this.memberJSDOC(method, ' ').trimLeft(); - } - + if (methodName === '__call') + methodName = '(call)'; const docClass = this.docClassForName(className); let method; if (docClass) { @@ -591,8 +574,6 @@ class TypesGenerator { 'PlaywrightWorkerArgs.playwright', 'PlaywrightWorkerOptions.defaultBrowserType', 'Project', - 'SuiteFunction', - 'TestFunction', ]), doNotExportClassNames: assertionClasses, }); diff --git a/utils/generate_types/overrides-test.d.ts b/utils/generate_types/overrides-test.d.ts index 54fffb5345851..ff46ba0e5c2d7 100644 --- a/utils/generate_types/overrides-test.d.ts +++ b/utils/generate_types/overrides-test.d.ts @@ -75,52 +75,83 @@ export type TestDetails = { annotation?: TestDetailsAnnotation | TestDetailsAnnotation[]; } -interface SuiteFunction { - (title: string, callback: () => void): void; - (callback: () => void): void; - (title: string, details: TestDetails, callback: () => void): void; -} +type TestBody = (args: TestArgs, testInfo: TestInfo) => Promise | void; +type ConditionBody = (args: TestArgs) => boolean; -interface TestFunction { - (title: string, body: (args: TestArgs, testInfo: TestInfo) => Promise | void): void; - (title: string, details: TestDetails, body: (args: TestArgs, testInfo: TestInfo) => Promise | void): void; -} +export interface TestType { + (title: string, body: TestBody): void; + (title: string, details: TestDetails, body: TestBody): void; + + only(title: string, body: TestBody): void; + only(title: string, details: TestDetails, body: TestBody): void; + + describe: { + (title: string, callback: () => void): void; + (callback: () => void): void; + (title: string, details: TestDetails, callback: () => void): void; + + only(title: string, callback: () => void): void; + only(callback: () => void): void; + only(title: string, details: TestDetails, callback: () => void): void; -export interface TestType extends TestFunction { - only: TestFunction; - describe: SuiteFunction & { - only: SuiteFunction; - skip: SuiteFunction; - fixme: SuiteFunction; - serial: SuiteFunction & { - only: SuiteFunction; + skip(title: string, callback: () => void): void; + skip(callback: () => void): void; + skip(title: string, details: TestDetails, callback: () => void): void; + + fixme(title: string, callback: () => void): void; + fixme(callback: () => void): void; + fixme(title: string, details: TestDetails, callback: () => void): void; + + serial: { + (title: string, callback: () => void): void; + (callback: () => void): void; + (title: string, details: TestDetails, callback: () => void): void; + + only(title: string, callback: () => void): void; + only(callback: () => void): void; + only(title: string, details: TestDetails, callback: () => void): void; }; - parallel: SuiteFunction & { - only: SuiteFunction; + + parallel: { + (title: string, callback: () => void): void; + (callback: () => void): void; + (title: string, details: TestDetails, callback: () => void): void; + + only(title: string, callback: () => void): void; + only(callback: () => void): void; + only(title: string, details: TestDetails, callback: () => void): void; }; + configure: (options: { mode?: 'default' | 'parallel' | 'serial', retries?: number, timeout?: number }) => void; }; - skip(title: string, body: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise | void): void; - skip(title: string, details: TestDetails, body: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise | void): void; + + skip(title: string, body: TestBody): void; + skip(title: string, details: TestDetails, body: TestBody): void; skip(): void; skip(condition: boolean, description?: string): void; - skip(callback: (args: TestArgs & WorkerArgs) => boolean, description?: string): void; - fixme(title: string, body: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise | void): void; - fixme(title: string, details: TestDetails, body: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise | void): void; + skip(callback: ConditionBody, description?: string): void; + + fixme(title: string, body: TestBody): void; + fixme(title: string, details: TestDetails, body: TestBody): void; fixme(): void; fixme(condition: boolean, description?: string): void; - fixme(callback: (args: TestArgs & WorkerArgs) => boolean, description?: string): void; + fixme(callback: ConditionBody, description?: string): void; + fail: { - (title: string, body: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise | void): void; - (title: string, details: TestDetails, body: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise | void): void; + (title: string, body: TestBody): void; + (title: string, details: TestDetails, body: TestBody): void; (condition: boolean, description?: string): void; - (callback: (args: TestArgs & WorkerArgs) => boolean, description?: string): void; + (callback: ConditionBody, description?: string): void; (): void; - only: TestFunction; + + only(title: string, body: TestBody): void; + only(title: string, details: TestDetails, body: TestBody): void; } + slow(): void; slow(condition: boolean, description?: string): void; - slow(callback: (args: TestArgs & WorkerArgs) => boolean, description?: string): void; + slow(callback: ConditionBody, description?: string): void; + setTimeout(timeout: number): void; beforeEach(inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise | any): void; beforeEach(title: string, inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise | any): void; diff --git a/utils/generate_types/parseOverrides.js b/utils/generate_types/parseOverrides.js index ad80ea388f233..bb96013842275 100644 --- a/utils/generate_types/parseOverrides.js +++ b/utils/generate_types/parseOverrides.js @@ -101,9 +101,9 @@ async function parseOverrides(filePath, commentForClass, commentForMethod, extra * @param {ts.Node} node */ function visitProperties(className, prefix, node) { - // This function supports structs like "a: { b: string; c: number, (): void }" - // and inserts comments for "a.b", "a.c", a. - if (ts.isPropertySignature(node)) { + // This function supports structs like "a: { b: string; c: number, (): void, d(): void }" + // and inserts comments for "a.b", "a.c", "a", "a.d". + if (ts.isPropertySignature(node) || ts.isMethodSignature(node)) { const name = checker.getSymbolAtLocation(node.name).getName(); const pos = node.getStart(file, false); replacers.push({