Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

automatic command doc gen for plugins #18029

Merged
merged 5 commits into from
Jan 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 4 additions & 4 deletions packages/execute-driver-plugin/lib/execute-child.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {attach} from 'webdriverio';

const log = logger.getLogger('ExecuteDriver Child');
/**
* @type {Promise<void>}
* @type {(res: ScriptResult) => Promise<void>}
*/
let send;

Expand Down Expand Up @@ -176,8 +176,8 @@ if (require.main === module && _.isFunction(process.send)) {

/**
* @typedef ScriptResult
* @property {any} success
* @property {ScriptResultError} error
* @property {any} [success]
* @property {ScriptResultError} [error]
*/

/**
Expand All @@ -189,5 +189,5 @@ if (require.main === module && _.isFunction(process.send)) {
/**
* @typedef RunScriptResult
* @property {any} result
* @property {Object} logs
* @property {object} logs
*/
5 changes: 3 additions & 2 deletions packages/execute-driver-plugin/lib/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,16 @@ export default class ExecuteDriverPlugin extends BasePlugin {
* a new nodejs VM, and which has available a webdriverio driver object, having
* already been attached to the currently running session.
*
* @param {function} next - standard behaviour for executeDriverScript
* @param {import('@appium/types').NextPluginCallback} next - standard behaviour for executeDriverScript
* @param {import('@appium/types').ExternalDriver} driver - Appium driver handling this command
* @param {string} script - the string representing the driver script to run
* @param {string} [scriptType='webdriverio'] - the name of the driver script
* library (currently only webdriverio is supported)
* @param {number} [timeoutMs=3600000] - timeout for the script process
*
* @returns {Object} - a JSONifiable object representing the return value of
* @returns {Promise<any>} - a JSONifiable object representing the return value of
Copy link
Contributor Author

@boneskull boneskull Jan 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that an invalid return type (non-Promise<T>) prevents documentation from getting generated for a command, so we need to be careful about it. No error will be generated by TS even though it's an async function (which must return a Promise<T>). TS (and thus TypeDoc) "believe" the function returns whatever is in @returns.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep good to know. i'm sure this was my type mistake

* the script
* @type {import('@appium/types').PluginCommand<[string, string?, number?]>}
* @throws {Error}
*/
async executeDriverScript(
Expand Down
10 changes: 7 additions & 3 deletions packages/execute-driver-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
},
"license": "Apache-2.0",
"author": "https://github.com/appium",
"types": "./build/lib/plugin.d.ts",
"files": [
"build",
"lib",
Expand All @@ -46,6 +47,10 @@
"peerDependencies": {
"appium": "^2.0.0-beta.35"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0",
"npm": ">=8"
},
"publishConfig": {
"access": "public"
},
Expand All @@ -54,8 +59,7 @@
"mainClass": "ExecuteDriverPlugin"
},
"gitHead": "5c7af8ee73078018e4ec52fccf19fe3f77249d72",
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0",
"npm": ">=8"
"typedoc": {
"entryPoint": "./lib/plugin.js"
}
}
3 changes: 2 additions & 1 deletion packages/execute-driver-plugin/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"compilerOptions": {
"outDir": "build"
"outDir": "build",
"checkJs": true
},
"extends": "@appium/tsconfig/tsconfig.plugin.json",
"include": ["lib"]
Expand Down
13 changes: 8 additions & 5 deletions packages/images-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"firefoxos",
"testing"
],
"homepage": "https://appium.io",
"bugs": {
"url": "https://github.com/appium/appium/issues"
},
Expand All @@ -22,6 +23,7 @@
},
"license": "Apache-2.0",
"author": "https://github.com/appium",
"types": "./build/lib/plugin.d.ts",
"files": [
"build",
"docs",
Expand All @@ -43,15 +45,16 @@
"peerDependencies": {
"appium": "^2.0.0-beta.35"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0",
"npm": ">=8"
},
"appium": {
"pluginName": "images",
"mainClass": "ImageElementPlugin"
},
"types": "./build/lib/plugin.d.ts",
"gitHead": "5c7af8ee73078018e4ec52fccf19fe3f77249d72",
"homepage": "https://appium.io",
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0",
"npm": ">=8"
"typedoc": {
"entryPoint": "./lib/plugin.js"
}
}
26 changes: 15 additions & 11 deletions packages/relaxed-caps-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@
"name": "@appium/relaxed-caps-plugin",
"version": "1.0.0-beta.14",
"description": "An Appium 2.0 plugin that loosens requirements for vendor prefixes on caps",
"keywords": [
"automation",
"javascript",
"selenium",
"webdriver",
"ios",
"android",
"firefoxos",
"testing"
],
"homepage": "https://appium.io",
"bugs": {
"url": "https://github.com/appium/appium/issues"
},
Expand All @@ -12,6 +23,7 @@
},
"license": "Apache-2.0",
"author": "https://github.com/appium",
"types": "./build/lib/plugin.d.ts",
"directories": {
"lib": "./lib"
},
Expand Down Expand Up @@ -45,15 +57,7 @@
"tags": [
"appium"
],
"homepage": "https://appium.io",
"keywords": [
"automation",
"javascript",
"selenium",
"webdriver",
"ios",
"android",
"firefoxos",
"testing"
]
"typedoc": {
"entryPoint": "./lib/plugin.js"
}
}
4 changes: 2 additions & 2 deletions packages/typedoc-plugin-appium/lib/converter/comment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import _ from 'lodash';
import {Comment, CommentDisplayPart} from 'typedoc';
import {AsyncMethodDeclarationReflection, KnownMethods} from './types';
import {CommandMethodDeclarationReflection, KnownMethods} from './types';

export const stats = _.fill(new Array(5), 0);

Expand All @@ -21,7 +21,7 @@ export const stats = _.fill(new Array(5), 0);
export function deriveComment(
command: string,
knownMethods?: KnownMethods,
refl?: AsyncMethodDeclarationReflection,
refl?: CommandMethodDeclarationReflection,
extraComment?: Comment
): CommentData | undefined {
const commentFinders: CommentFinder[] = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ export interface ConvertExecuteMethodMapOpts {
* If `true`, do not add a route if the method it references cannot be found
*/
strict?: boolean;
/**
* If `true`, handle commands as `PluginCommand`s, which affects which parameters get used
*/
isPluginCommand?: boolean;
}

/**
Expand All @@ -52,6 +56,7 @@ export function convertExecuteMethodMap({
execMethodMapRefl,
methods,
strict = false,
isPluginCommand = false,
}: ConvertExecuteMethodMapOpts): ExecMethodDataSet {
const commandRefs: ExecMethodDataSet = new Set();
if (!execMethodMapRefl) {
Expand Down Expand Up @@ -114,6 +119,7 @@ export function convertExecuteMethodMap({
refl: method,
comment: commentData?.comment,
commentSource: commentData?.commentSource,
isPluginCommand,
})
);

Expand Down
25 changes: 20 additions & 5 deletions packages/typedoc-plugin-appium/lib/converter/external.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import _ from 'lodash';
import pluralize from 'pluralize';
import {Context, ReflectionKind} from 'typedoc';
import {
isBasePluginConstructorDeclarationReflection,
isClassDeclarationReflection,
isConstructorDeclarationReflection,
isExecMethodDefReflection,
isMethodMapDeclarationReflection,
} from '../guards';
Expand All @@ -27,7 +29,7 @@ import {
} from './utils';

/**
* Name of the static `newMethodMap` property in a Driver
* Name of the static `newMethodMap` property in a Driver or Plugin
*/
export const NAME_NEW_METHOD_MAP = 'newMethodMap';

Expand Down Expand Up @@ -58,6 +60,8 @@ export const NAME_COMMAND = 'command';
*/
export const NAME_PAYLOAD_PARAMS = 'payloadParams';

export const NAME_BASE_PLUGIN = 'BasePlugin';

/**
* Converts declarations to information about Appium commands
*/
Expand Down Expand Up @@ -129,6 +133,7 @@ export class ExternalConverter extends BaseConverter<ProjectCommands> {
* 3. Parse the `newMethodMap` of each class, if any
* 4. For each method, look for it in either `newMethodMap` or the known methods
* 5. Handle execute methods
*
* @param parentRefl - Project or module
* @returns Info about the commands in given `parent`
*/
Expand All @@ -139,6 +144,10 @@ export class ExternalConverter extends BaseConverter<ProjectCommands> {
const classReflections = filterChildrenByGuard(parentRefl, isClassDeclarationReflection);

for (const classRefl of classReflections) {
const isPlugin = isBasePluginConstructorDeclarationReflection(
findChildByGuard(classRefl, isConstructorDeclarationReflection)
);

const methods = findAsyncMethodsInReflection(classRefl, this.knownMethods);

if (!methods.size) {
Expand All @@ -152,10 +161,10 @@ export class ExternalConverter extends BaseConverter<ProjectCommands> {
pluralize('potential method', methods.size, true)
);

const newRouteMap = this.#findAndConvertNewMethodMap(classRefl, methods);
const newRouteMap = this.#findAndConvertNewMethodMap(classRefl, methods, isPlugin);
routeMap = new Map([...routeMap, ...newRouteMap]);

const newExecMethodData = this.#findAndConvertExecMethodMap(classRefl, methods);
const newExecMethodData = this.#findAndConvertExecMethodMap(classRefl, methods, isPlugin);
execMethodData = new Set([...execMethodData, ...newExecMethodData]);

const overriddenRouteMap: RouteMap = this.builtinCommands
Expand Down Expand Up @@ -187,11 +196,13 @@ export class ExternalConverter extends BaseConverter<ProjectCommands> {
* If the class has an `executeMethodMap`, convert it
* @param classRefl A class
* @param methods Methods in said class
* @param isPluginCommand If `classRefl` represents an Appium Plugin or not
* @returns A set of exec method data which may be empty
*/
#findAndConvertExecMethodMap(
classRefl: ClassDeclarationReflection,
methods: KnownMethods
methods: KnownMethods,
isPluginCommand?: boolean
): ExecMethodDataSet {
const execMethodMapRefl = findChildByGuard(classRefl, isExecMethodDefReflection);
if (!execMethodMapRefl) {
Expand All @@ -203,18 +214,21 @@ export class ExternalConverter extends BaseConverter<ProjectCommands> {
execMethodMapRefl,
methods,
strict: true,
isPluginCommand,
});
}

/**
* If the class has a `newMethodMap`, convert it
* @param classRefl A class
* @param methods Methods in said class
* @param isPluginCommand If `classRefl` represents an Appium Plugin or not
* @returns A map of routes which may be empty
*/
#findAndConvertNewMethodMap(
classRefl: ClassDeclarationReflection,
methods: KnownMethods
methods: KnownMethods,
isPluginCommand?: boolean
): RouteMap {
const newMethodMapRefl = findChildByNameAndGuard(
classRefl,
Expand All @@ -232,6 +246,7 @@ export class ExternalConverter extends BaseConverter<ProjectCommands> {
methods,
knownMethods: this.knownMethods,
strict: true,
isPluginCommand,
});
}
}
7 changes: 7 additions & 0 deletions packages/typedoc-plugin-appium/lib/converter/method-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ export interface ConvertMethodMapOpts {
* If `true`, do not add a route if the method it references cannot be found
*/
strict?: boolean;

/**
* If `true`, handle commands as `PluginCommand`s, which affects which parameters get used
*/
isPluginCommand?: boolean;
}

/**
Expand All @@ -60,6 +65,7 @@ export function convertMethodMap({
methods,
knownMethods = new Map(),
strict = false,
isPluginCommand = false,
}: ConvertMethodMapOpts): RouteMap {
const routes: RouteMap = new Map();

Expand Down Expand Up @@ -129,6 +135,7 @@ export function convertMethodMap({
commentSource: commentData?.commentSource,
refl: method,
parentRefl,
isPluginCommand,
})
);

Expand Down