Skip to content

getByRole expecting incorrect parameters #22

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

Closed
sazzer opened this issue Jun 19, 2021 · 5 comments
Closed

getByRole expecting incorrect parameters #22

sazzer opened this issue Jun 19, 2021 · 5 comments

Comments

@sazzer
Copy link

sazzer commented Jun 19, 2021

I'm assuming that I'm doing something wrong here, but I can't work out what. :(

I've just converted my (fledgling) WebdriverIO E2E tests from JavaScript to TypeScript, and the places that I'm calling testing-library functions are complaining in a strange way.

For example, I've got:

export class BasePage {
  get header() {
    return browser.getByRole('navigation').then((element) => new HeaderBar(element));
  }
}

And then tsc complains with:

$ tsc
src/pageobjects/base/index.ts:11:30 - error TS2345: Argument of type '"navigation"' is not assignable to parameter of type 'ByRoleOptions | undefined'.

11     return browser.getByRole('navigation').then((element) => new HeaderBar(element));

However, I can't see why this is happening. getByRole is meant to take two parameters, of which ByRoleOptions | undefined is the second one, and 'navigation' is perfectly valid for what is meant to be the first parameter.

I've defined this module in my code:

import { WebdriverIOQueries } from '@testing-library/webdriverio';

declare global {
  namespace WebdriverIO {
    interface Browser extends WebdriverIOQueries {}
    interface Element extends WebdriverIOQueries {}
  }
}

This means that the functions themselves are found, but all seem to be expecting only the final parameter instead of the correct ones.

Have I missed something obvious? If so, what? :)

Cheers

@sazzer
Copy link
Author

sazzer commented Jun 19, 2021

To add to this, if I instead use setupBrowser in every page object / step as follows:

    const { getByRole } = setupBrowser(browser);

    return getByRole('navigation').then((element: WebdriverIO.Element) => new HeaderBar(element));

Then this has exactly the same errors, so I don't think it's anything to do with having done setupBrowser once in a before function.

Also, the code works fine. If I make it:

    return browser.getByRole('navigation' as any).then((element) => new HeaderBar(element));

then it builds and runs perfectly fine. So it's not the code but the typing that I'm struggling with.

Cheers

@sazzer
Copy link
Author

sazzer commented Jun 19, 2021

Even more curious, I've just written a tiny bit of code using @testing-library/react instead of @testing-library/webdriverio as follows:

  const result = render(<div></div>);
  result.getByRole("navigation");

This builds perfectly well with tsc, unsurprisingly. But Cmnd-clicking on the getByRole call takes me to the same line of the same file. In both cases, I end up on line 184 of @testing-library/dom/types/queries.d.ts. And, in fact, in both cases it's version 7.31.2 of @testing-library/dom that I'm ending up in, so it's exactly the same. Just works in my React project and not my WebdriverIO one.

@sazzer
Copy link
Author

sazzer commented Jun 19, 2021

And just like that - I've got a fix :)

Apparently, my tsconfig.json needs to have dom in the lib setting, even though it's not running in a web browser and isn't actually interacting with the DOM directly. I assume that the way @testing-library/webdriverio works assumes some of those definitions are available?

Well score one for a solution :)

I'm leaving this open just in case you feel it's worth adding any docs, but feel free to close it since I've got things working now.

Cheers

@olivierwilkinson
Copy link
Collaborator

olivierwilkinson commented Jun 20, 2021

Hi 👋

Thanks for raising this, we should definitely update the docs to include a note in the Typescript section so this is clear for anybody finding the same! I'm going to keep this issue open until we have updated the docs 😄

I spent some time digging into why this happens so I could to be certain of the root cause and fix it if it's something to do with webdriverio-testing-library:

Under the hood I used the types from dom-testing-library to create the types for webdriverio-testing-library, this was so that the available parameters and options would match dom-testing-library queries, but the return values would always be a Promise and use the WebdriverIO.Element interface rather than HTMLElement.

dom-testing-library assumes that the dom lib is included globally as it uses the HTMLElement type everywhere. I hadn't noticed this before as Typescript includes dom types by default if the tsconfig does not specify "lib".

When the dom types aren't included then HTMLElement is no longer available, this causes a problem in dom-testing-library's BoundFunction type. When BoundFunction tries to infer the resulting type it treats the container parameter as any instead of HTMLElement causing it to map the parameters incorrectly, in this case options of the GetByRole type is getting mapped to the text parameter of the bound function.

type BoundGetByRole = BoundFunction<GetByRole>
// BoundGetByRole is (text: ByRoleOptions | undefined, options?: unknown) => any

Anyways I thought it was interesting, but none of this really matters as you have already got the solution! 😝

olivierwilkinson added a commit to olivierwilkinson/testing-library-docs that referenced this issue Jun 20, 2021
WebdriverIO Testing Library assumes that users include the DOM types in
their typescript default types. Add a note to the Typescript section of
the WTL docs to help users who are finding type errors when they haven't.

Related issue: testing-library/webdriverio-testing-library#22
olivierwilkinson added a commit to olivierwilkinson/testing-library-docs that referenced this issue Jun 20, 2021
WebdriverIO Testing Library assumes that users include the DOM types in
their typescript default types. Add a note to the Typescript section of
the WTL docs to help users who are finding type errors when they haven't.

Related issue: testing-library/webdriverio-testing-library#22
@olivierwilkinson
Copy link
Collaborator

The update to the docs has been merged 🎉

Thanks again for raising this and using the lib! Please don't hesitate to raise any other issues you find 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants