fix: correct types for things like `test.describe.only` (#33142)

This commit is contained in:
Dmitry Gozman 2024-10-17 03:34:05 -07:00 committed by GitHub
parent 7af9e93304
commit 2d150eec25
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 1039 additions and 363 deletions

File diff suppressed because it is too large Load Diff

View File

@ -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,
});

View File

@ -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<TestArgs> = (args: TestArgs, testInfo: TestInfo) => Promise<void> | void;
type ConditionBody<TestArgs> = (args: TestArgs) => boolean;
interface TestFunction<TestArgs> {
(title: string, body: (args: TestArgs, testInfo: TestInfo) => Promise<void> | void): void;
(title: string, details: TestDetails, body: (args: TestArgs, testInfo: TestInfo) => Promise<void> | void): void;
}
export interface TestType<TestArgs extends KeyValue, WorkerArgs extends KeyValue> {
(title: string, body: TestBody<TestArgs & WorkerArgs>): void;
(title: string, details: TestDetails, body: TestBody<TestArgs & WorkerArgs>): void;
export interface TestType<TestArgs extends KeyValue, WorkerArgs extends KeyValue> extends TestFunction<TestArgs & WorkerArgs> {
only: TestFunction<TestArgs & WorkerArgs>;
describe: SuiteFunction & {
only: SuiteFunction;
skip: SuiteFunction;
fixme: SuiteFunction;
serial: SuiteFunction & {
only: SuiteFunction;
only(title: string, body: TestBody<TestArgs & WorkerArgs>): void;
only(title: string, details: TestDetails, body: TestBody<TestArgs & WorkerArgs>): 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;
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): void;
skip(title: string, details: TestDetails, body: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<void> | void): void;
skip(title: string, body: TestBody<TestArgs & WorkerArgs>): void;
skip(title: string, details: TestDetails, body: TestBody<TestArgs & WorkerArgs>): 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): void;
fixme(title: string, details: TestDetails, body: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<void> | void): void;
skip(callback: ConditionBody<TestArgs & WorkerArgs>, description?: string): void;
fixme(title: string, body: TestBody<TestArgs & WorkerArgs>): void;
fixme(title: string, details: TestDetails, body: TestBody<TestArgs & WorkerArgs>): void;
fixme(): void;
fixme(condition: boolean, description?: string): void;
fixme(callback: (args: TestArgs & WorkerArgs) => boolean, description?: string): void;
fixme(callback: ConditionBody<TestArgs & WorkerArgs>, description?: string): void;
fail: {
(title: string, body: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<void> | void): void;
(title: string, details: TestDetails, body: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<void> | void): void;
(title: string, body: TestBody<TestArgs & WorkerArgs>): void;
(title: string, details: TestDetails, body: TestBody<TestArgs & WorkerArgs>): void;
(condition: boolean, description?: string): void;
(callback: (args: TestArgs & WorkerArgs) => boolean, description?: string): void;
(callback: ConditionBody<TestArgs & WorkerArgs>, description?: string): void;
(): void;
only: TestFunction<TestArgs & WorkerArgs>;
only(title: string, body: TestBody<TestArgs & WorkerArgs>): void;
only(title: string, details: TestDetails, body: TestBody<TestArgs & WorkerArgs>): void;
}
slow(): void;
slow(condition: boolean, description?: string): void;
slow(callback: (args: TestArgs & WorkerArgs) => boolean, description?: string): void;
slow(callback: ConditionBody<TestArgs & WorkerArgs>, description?: string): void;
setTimeout(timeout: number): void;
beforeEach(inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<any> | any): void;
beforeEach(title: string, inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<any> | any): void;

View File

@ -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({