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

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

Open
ctrl-brk opened this Issue Mar 16, 2017 · 11 comments

Comments

Projects
None yet
10 participants
@ctrl-brk

ctrl-brk commented Mar 16, 2017

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

@codeandcats

This comment has been minimized.

Show comment
Hide comment
@codeandcats

codeandcats Mar 17, 2017

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.

codeandcats commented Mar 17, 2017

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.

@ctrl-brk ctrl-brk changed the title from Promise<String>.toEqual does not accept string parameter. Reqires also Promise. to Promise<String>.toEqual does not accept string parameter. Requires also Promise. Mar 17, 2017

@lukas-zech-software

This comment has been minimized.

Show comment
Hide comment
@lukas-zech-software

lukas-zech-software Mar 17, 2017

Contributor

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.

Contributor

lukas-zech-software commented Mar 17, 2017

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.

@lukas-zech-software

This comment has been minimized.

Show comment
Hide comment
@lukas-zech-software

lukas-zech-software Mar 17, 2017

Contributor

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

Contributor

lukas-zech-software commented Mar 17, 2017

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

@codeandcats

This comment has been minimized.

Show comment
Hide comment
@codeandcats

codeandcats Mar 17, 2017

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.

codeandcats commented Mar 17, 2017

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.

@18steps

This comment has been minimized.

Show comment
Hide comment
@18steps

18steps Apr 30, 2017

Contributor

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

18steps commented Apr 30, 2017

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

This comment has been minimized.

Show comment
Hide comment
@raghulrajnkl

raghulrajnkl Jun 14, 2017

expect(
to
expect(

its worked for me

raghulrajnkl commented Jun 14, 2017

expect(
to
expect(

its worked for me

@ValterSantosMatos

This comment has been minimized.

Show comment
Hide comment
@ValterSantosMatos

ValterSantosMatos Jun 21, 2017

Installing@types/jasminewd work for me, from link

ValterSantosMatos commented Jun 21, 2017

Installing@types/jasminewd work for me, from link

@DPGrev DPGrev referenced this issue Jun 24, 2017

Open

Runnnig tests #9

@xino1010

This comment has been minimized.

Show comment
Hide comment
@xino1010

xino1010 Oct 23, 2017

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

this solve the problem

xino1010 commented Oct 23, 2017

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

this solve the problem

@tempoc

This comment has been minimized.

Show comment
Hide comment
@tempoc

tempoc Nov 28, 2017

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)

tempoc commented Nov 28, 2017

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)

@kahan002

This comment has been minimized.

Show comment
Hide comment
@kahan002

kahan002 Feb 25, 2018

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

kahan002 commented Feb 25, 2018

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

@aktraore

This comment has been minimized.

Show comment
Hide comment
@aktraore

aktraore Mar 21, 2018

installing @types/jasminewd2 solved the issue for me

aktraore commented Mar 21, 2018

installing @types/jasminewd2 solved the issue for me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment