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

  • 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 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.

15 Answers

✔️Accepted Answer

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:
    #14579
    #14569
    #14338
    #13994 (comment)

  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

Other Answers:

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

Installing@types/jasminewd work for me, from link

installing @types/jasminewd2 solved the issue for me

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.

More Issues: