Definitelytyped: Promise<String>.toEqual does not accept string parameter. Requires also Promise.

Created on 16 Mar 2017  ·  13Comments  ·  Source: DefinitelyTyped/DefinitelyTyped

  • [x] I tried using the @types/2.5.46 package and had problems.
  • [ ] I tried using the latest stable version of tsc. https://www.npmjs.com/package/typescript
  • [ ] I have a question that is inappropriate for StackOverflow. (Please ask any appropriate questions there).
  • [ ] [Mention](https://github.com/blog/821-mention-somebody-they-re-notified) the authors (see Definitions by: in index.d.ts) so they can respond.

In 2.5.45 I was able to do something like that:
expect(element(by.id('id')).getAttribute('attr')).toEqual('myValue');
Now it gives me an error
TS2345:Argument of type '"myValue"' is not assignable to parameter of type 'Expected<Promise<string>>'.

It stops complaining if I add .toString after getAttribute but I'm not sure it will work.

Most helpful comment

Until this is fixed there are several workarounds:

  1. Fix the version of the typings to 2.5.45
    This will simply use the latest working version.
    Fixing the version of typings seems to become a Best practise anyway as typings cannot follow SemVer and changes in minor version can easily break your build.
    See these issues:
    https://github.com/DefinitelyTyped/DefinitelyTyped/issues/14579
    https://github.com/DefinitelyTyped/DefinitelyTyped/issues/14569
    https://github.com/DefinitelyTyped/DefinitelyTyped/issues/14338
    https://github.com/DefinitelyTyped/DefinitelyTyped/pull/13994#issuecomment-275949045

  2. Use any as generic parameter for expect
    The new typings still let you have the old behaviour, you just need to specify explictily that you want to use any as type like this

expect<any>(element(by.id('id')).getAttribute('attr')).toEqual('myValue');
  1. Write typings for the async expect functions and add it to your project
    This would be the best solution but should be done by Protractor
    It would probably look something like
    // UNTESTED CODE!
    interface AsyncMatchers<T> extends Matchers<Promise<T>> {
        toBe(expected: Expected<T>, expectationFailOutput?: any): boolean;
        toEqual(expected: Expected<T>, expectationFailOutput?: any): boolean;
        toContain(expected: T, expectationFailOutput?: any): boolean;
        not: AsyncMatchers<T>;
    }

Add this code in a protractor.d.ts in your project somewhere the TypeScript compiler can see it and it should resolve your issues, given the promise in expect actually resolves to the type provided in toEqual

All 13 comments

Yep, this is a big problem for anyone using protractor in TypeScript.

It seems Jasmine (or perhaps Protractor's version of Jasmine if it modifies it - I'm not sure?) supports expecting a promise and then testing the resolved value of the promise, without the test author having to resolve the promise themselves.

It looks like @lukas-zech-software made the matches generic, which is really cool, but breaks passing in promises and matching against their resolved values.

As already mentioned in the PR's comments this is nothing the jasmine typings can do about.

Protractor extends the functionality so it has to provide the typings for this.
If the would be any typings for protractor on DefinitelyTyped this would have occurred during the tests but there aren't so I cannot fix this here.
Actually Protractor does not provide any typings at all for this, so they simply rely on expect accepting any as parameter

I can hardly add typings for an async expect which will not work in jasmine itself.
Please open an issue with protractor and ask them to extend the jasmine typings correctly.

Until this is fixed there are several workarounds:

  1. Fix the version of the typings to 2.5.45
    This will simply use the latest working version.
    Fixing the version of typings seems to become a Best practise anyway as typings cannot follow SemVer and changes in minor version can easily break your build.
    See these issues:
    https://github.com/DefinitelyTyped/DefinitelyTyped/issues/14579
    https://github.com/DefinitelyTyped/DefinitelyTyped/issues/14569
    https://github.com/DefinitelyTyped/DefinitelyTyped/issues/14338
    https://github.com/DefinitelyTyped/DefinitelyTyped/pull/13994#issuecomment-275949045

  2. Use any as generic parameter for expect
    The new typings still let you have the old behaviour, you just need to specify explictily that you want to use any as type like this

expect<any>(element(by.id('id')).getAttribute('attr')).toEqual('myValue');
  1. Write typings for the async expect functions and add it to your project
    This would be the best solution but should be done by Protractor
    It would probably look something like
    // UNTESTED CODE!
    interface AsyncMatchers<T> extends Matchers<Promise<T>> {
        toBe(expected: Expected<T>, expectationFailOutput?: any): boolean;
        toEqual(expected: Expected<T>, expectationFailOutput?: any): boolean;
        toContain(expected: T, expectationFailOutput?: any): boolean;
        not: AsyncMatchers<T>;
    }

Add this code in a protractor.d.ts in your project somewhere the TypeScript compiler can see it and it should resolve your issues, given the promise in expect actually resolves to the type provided in toEqual

Cool, thanks for clearing this up @lukas-zech-software. Appreciate the different solutions. I ended up locking the typings to an earlier version for now.

Suggest this can be closed.

Using async / await to "dereference" the promise works.

E.g. instead of

it('should have header', () => {
    let subject = element(by.css('h1')).isPresent();
    let result  = true;
    expect(subject).toEqual(result);
  });

have it as

it('should have header', async () => {
    let subject = await element(by.css('h1')).isPresent();
    let result  = true;
    expect(subject).toEqual(result);
  });

expect(
to
expect(

its worked for me

Installing@types/jasminewd work for me, from link

beforeEach(() => {
page = new xxx();
browser.waitForAngularEnabled(false);
});

this solve the problem

For me, adjusting tsconfig.e2e.json per this comment worked. My problem showed up when updating from Angular 4 to 5 on a CLI-managed project.
https://github.com/angular/protractor/issues/4176#issuecomment-310610380

If you can live with the imprecision, a different workaround seems to be jettisoning toEqual with the string and asking instead for toContain.

installing @types/jasminewd2 solved the issue for me

For me, adjusting tsconfig.e2e.json per this comment worked. My problem showed up when updating from Angular 4 to 5 on a CLI-managed project.
angular/protractor#4176 (comment)

Installing @types/jasminewd2 and doing this is the correct answer.

Notice, installation of @types/jasminewd2 __IS NOT__ a correct answer:

  • jasminewd2 is not necessarily compatible with jasmine typings for v3, as it's targeting jasmine v2
  • the reason it works is just a coincidence, as they any-d all the inputs.

The correct answer is either:

  • await result as described here
  • extend protractor typings or create new typings package which will properly extend jasmine
  • use expectAsync available in latest jasmine.
Was this page helpful?
0 / 5 - 0 ratings