getgauge / taiko

A node.js library for testing modern web applications
https://taiko.dev
MIT License
3.57k stars 453 forks source link

Docs not showing in IntelliSense #1515

Open fmpanelli opened 4 years ago

fmpanelli commented 4 years ago

Expected behavior

Since Taiko has support for Tyescript types, when editing in VS Code you will see IntelliSense suggestions for auto-completion including types for functions and arguments. I would expect also the JSDoc comments that are found in lib\taiko.js to be shown.

E.g. for openBrowser I would expect a formatted version of the following to be shown when hovering the function name in VS Code:

image

Actual behavior

The documentation is not shown, but only the types (actually it show "Browser Actions" which is wrong):

image

I guess this is because the comments are not present in types/taiko/index.d.ts but only in lib/taiko.js.

Steps to reproduce

  1. Create a typescript project
  2. Add taiko to the project npm i taiko
  3. Create file like the example.ts below
  4. Open the file in VS Code and just hover with the mouse above openBrowser
//example.ts
import {openBrowser} from taiko
await openBrowser();

Versions

fmpanelli commented 4 years ago

An unsustainable approach

A possible approach would be to copy the comments from lib/taiko.js to types/taiko/index.d.ts

That would create a huge duplication of information between the two files and make them practically un-mantainable.

A more reasonable solution (but is it feasible?)

An alternative which I would like to explore is to automatically generate the index.d.ts from lib/taiko.js's JSDoc, using the facilities provided by the TypeScript compiler since ver 3.7.

Although this is possible in theory, there are some points to be clarified:

  1. is it possible to write the JSDoc comments that is compatible both with the TypeScript compiler and with the documentation generator used by taiko?

  2. adding TypeScript to the project has consequences e.g. on eslint or similar?

Other approaches

Any other idea to approach the problem?

zabil commented 4 years ago

Thanks for picking this up and for all those PR's to add TypeScript support such great effort. Since I worked on setting up the documentation site I can add some context about document generation.

Taiko uses inline documentation to make documentation within the IDE's more accessible, this is important. The documentation at https://docs.taiko.dev/api/reference is parsed from JSDoc comment which are exported to json using https://documentation.js.org.

is it possible to write the JSDoc comments that is compatible both with the TypeScript compiler and with the documentation generator used by taiko?

I think it can be compatible since Taiko uses a custom parser that reads from an exported api.json file. It ignores other tags. So you could add Typescript specific tag and generate the *.d.ts file. It is also easy to tweak the parser to read TypeScript specific info in the generated documentation. From the TypeScript's JSDoc reference it looks like @example is the only extra tag that Taiko is using.

adding TypeScript to the project has consequences e.g. on eslint or similar?

If you meant eslint in the documentation, I don't think so.

fmpanelli commented 4 years ago

@zabil Thanks for the advice. And thanks to the whole team for the open and welcoming attitude in this community.

I am experimenting on my machine to understand the process of the automatic generation of declaration files and it looks promising (and I hope I will be able to reuse all the type tests built with the previous PR's).

For sure some changes to the JSDodc comments are required generate the correct types.

E.g. for the function into the type manually declared in index.d.ts is now:

// https://docs.taiko.dev/api/into
export function into<T extends string | Selector>(value: T): T;

In order to obtain the same result I had to change the JSDoc like this: image

This is the one of the easiest examples. Doing something like that for all the type declarations is gonna be challenging...

zabil commented 4 years ago

I used the sample above to generate the api.json using TypeScript style JSDoc

"tags": [
      {
        "title": "example",
        "description": "await write(\"user\", into(textBox('Username:')))",
        "lineNumber": 3
      },
      {
        "title": "template",
        "description": "{string|selector}",
        "lineNumber": 6
      },
      {
        "title": "param",
        "description": "value to be returned",
        "lineNumber": 7,
        "type": {
          "type": "NameExpression",
          "name": "T"
        },
        "name": "null-null"
      },
      {
        "title": "return",
        "description": "the value provided in input",
        "lineNumber": 8,
        "type": {
          "type": "NameExpression",
          "name": "T"
        }
      }
    ]

This is tough to parse as the info is not inside the scope of the parameters. However if I modify it to @type the documentation parser generates something that can easily be parsed

/**
 * This function is used to improve the readability. It simply returns the parameter passed into it.
 *
 * @example
 * await write("user", into(textBox('Username:')))
 *
 * @type {string|selector} 
 * @return {string|selector} 
 */
module.exports.into = (value) => value;

Generates

"tags": [
      {
        "title": "example",
        "description": "await write(\"user\", into(textBox('Username:')))",
        "lineNumber": 3
      },
      {
        "title": "type",
        "description": null,
        "lineNumber": 6,
        "type": {
          "type": "UnionType",
          "elements": [
            {
              "type": "NameExpression",
              "name": "string"
            },
            {
              "type": "NameExpression",
              "name": "selector"
            }
          ]
        }
      },

This should be easy to parse by the document generator. Do we really need to use @template? Shouldn't @param or @type work for generating the .d.ts file?

fmpanelli commented 4 years ago

Mmmmhh... I start to get the picture...

Let me think about it for a few days... Maybe I can come up with actual code we can discuss.

fmpanelli commented 4 years ago

I made some analysis and experimentation.

What I understood

  1. adding the infrastructure for the automatic generation of type declarations is rather easy
  2. when you do that, you have JSDoc comments that are used at the same time to generate the types and to generate the documentation website
  3. the comments of the apis in taiko.js and in the classes under lib/ as they are today don't enable the automatically generated types to reach the same quality of the manual declarations and they will need improvements
  4. the mechanism for generating the docs.taiko.dev website documentation is currently able to represent correctly the basic types and it can be gradually extended to deal with more complex types (e.g. it already supports methods returning instances of lib/elementWrapper/*.js classes)
  5. the improvements needed probably include: a. types today are shown only for apis which do return a Promiseor a *Wrapper object, but not a type like string b. function params with types like {string|number} do not get a type displayed on the page c. function params which are instances of a class do not get a type displayed on the page d. definition of types with @typedef is ignored by the documentation system, we may want to treat it with a dedicated typedef.njk similar to class.njk
  6. the website generation mechanism must be evolved prior or in parallel with the evolution of the JSDoc's required for automatic type generation, to prevent the docs website from breaking

I guess all of the previous points (except maybe no. 5) were already inside the suggestions of @zabil, but now I fully understand 😀

Proposition for a roadmap

If you agree I would propose to proceed as follows:

  1. We start by raising some issues and posting some PRs to improve the ability of the documentation generation to handle types as described in point no. 5 above, in doing so we also improve the testing of the documentation generation
  2. We enable the automatic type generation, but we keep on using the manually-written type declarations when publishing the library
  3. We clone the type tests I wrote for the manually-written declaration and we apply them to the automatically-generated declarations --> conceptually when the tests pass, the automatically-generated types are ready for publishing
  4. when we are ready, we start using the automatically generated type declarations in the publishing and we throw away the manual declarations

@zabil, if you are ok with that I can start working on this plan

zabil commented 4 years ago

👍 This sounds good.