Skip to content
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

after upgrade to ^3.0.0-rc.32", i got compilation error using CallAnApi.using(axiosInstance) (with axios 1.1.3) #1342

Closed
LayMui opened this issue Oct 26, 2022 · 12 comments
Labels
enhancement A good idea that should be implemented

Comments

@LayMui
Copy link
Sponsor

LayMui commented Oct 26, 2022

test:consent:stage] TSError: ⨯ Unable to compile TypeScript:
[test:consent:stage] src/Actors.ts(18,29): error TS2345: Argument of type 'import("/Users/xxxxx/dev/sh-common-services-serenityjs/node_modules/axios/index").AxiosInstance' is not assignable to parameter of type 'import("/Users/xxxxxxx/dev/sh-common-services-serenityjs/node_modules/@serenity-js/rest/node_modules/axios/index").AxiosInstance'.
[test:consent:stage] The types of 'defaults.headers.common' are incompatible between these types.
[test:consent:stage] Type 'Partial<RawAxiosHeaders & MethodsHeaders & CommonHeaders>' is not assignable to type 'AxiosRequestHeaders'.
[test:consent:stage] 'string' index signatures are incompatible.
[test:consent:stage] Type 'AxiosHeaderValue' is not assignable to type 'string | number | boolean'.
[test:consent:stage] Type 'AxiosHeaders' is not assignable to type 'string | number | boolean'.
[tes

Actors.ts:

    baseURL: process.env.WEATHER_SERVICE_BASE_URL,
    timeout: 5000,
    headers: { Accept: 'application/json' },
});
export class Actors implements Cast {
    constructor(private readonly baseApiUrl: string) {
        ensure('apiUrl', baseApiUrl, isNotBlank());
    }

    prepare(actor: Actor): Actor {        
        return actor.whoCan(
            CallAnApi.using(axiosInstance),
            TakeNotes.usingAnEmptyNotepad(),
        );
    }
}

package.json

  "@cucumber/cucumber": "^8.3.1",
    "@serenity-js/assertions": "^3.0.0-rc.32",
    "@serenity-js/console-reporter": "^3.0.0-rc.32",
    "@serenity-js/core": "^3.0.0-rc.32",
    "@serenity-js/cucumber": "^3.0.0-rc.32",
    "@serenity-js/rest": "^3.0.0-rc.32",
    "@serenity-js/serenity-bdd": "^3.0.0-rc.32",
    "@types/node": "^18.0.0",
    "@typescript-eslint/eslint-plugin": "^5.29.0",
    "@typescript-eslint/parser": "^5.29.0",
    "axios": "^1.1.3",
    "axios-debug-log": "^0.8.4",
    "axios-mock-adapter": "^1.20.0",
@viper3400
Copy link
Sponsor Collaborator

Hi @LayMui , looks like you use axios version 1.1.3, could you try to downgrade to the version serenity-js/rest is using (^0.27.2).

"axios": "^0.27.2"

@jan-molak , we already had this issue, see #1223 , looks as it‘s back in axios 1.x

@LayMui
Copy link
Sponsor Author

LayMui commented Oct 27, 2022

yes. I fixed the axios version to 0.27.2
however when I upgrade the serenityjs version from "^3.0.0-rc.19", to "^3.0.0-rc.32",

I got the following error

[test:weather:stage] TSError: ⨯ Unable to compile TypeScript:
[test:weather:stage] src/task/consent/VerifyBundleDetails.ts(154,81): error TS2445: Property 'description' is protected and only accessible within class 'Activity' and its subclasses.

here is the code snippet:

Ensure.that(
                LastResponse.body<Bundle<BundleData>>().data.confirmationDialog.description.answeredBy(actor), matches(/\w+/)
            ),

BundleData.ts

import Document from "./Document";

interface BundleData {
    id: string,
    title: string,
    subtitle: string,
    acceptLabel:string,
    declineLabel: string,
    confirmationDialog: {
        title: string,
        description: string,
        confirmLabel: string,
        cancelLabel: string
    },
    description: string,
    product: string,
    type: string,
    lang: string,
    country: string[],
    documents: Document 
}

export default BundleData;

@viper3400
Copy link
Sponsor Collaborator

viper3400 commented Oct 27, 2022

Well, looks like at least the axios error has gone, right? 😕

Now you've got a new error: Is this error related to the upgrade to the latest Serenity/JS version? Has this code worked with version 3.0.0-rc.19 which you've used before?

I assume the snippet you've pasted is line 154 from src/task/consent/VerifyBundleDetails.ts: I think, you do not need the answeredBy(actor) part when using Ensure in combination with LastResponse.

Something like

Ensure.that(
  LastResponse.body<Bundle<BundleData>>().data.confirmationDialog.description, matches(/\w+/)
 )

should do the trick. See this example:

Ensure.that(LastResponse.body<Product>().name.toLocaleUpperCase(), equals('APPLE')),

In case this does not help: You expect a response of type <Bundle<<BundleData>>. You provided just the BundleData interface, can you please provide the Bundle interface as well?

@LayMui
Copy link
Sponsor Author

LayMui commented Oct 28, 2022

Bundle.ts

import BundleData from "./BundleData";

interface Bundle<T>{
    status: string,
    errors:  {
        msg: string[],
        errorCode: number
    },
    data: T,
}

export default Bundle;

@LayMui
Copy link
Sponsor Author

LayMui commented Oct 28, 2022

yes the axios issue is resolved.
this is another issue due to the upgrade from ^3.0.0-rc.19 to ^3.0.0-rc.32

@viper3400
Copy link
Sponsor Collaborator

Did you try to remove the answeredBy(actor), as well?

I wonder if you would do a downgrade to 3.0.0-rc.19 , if your test is working again?

@viper3400
Copy link
Sponsor Collaborator

Okay, think I found something. You try to access the property called description. But this get’s resolved to

protected readonly description: string,

Have to have a deeper look.

@LayMui
Copy link
Sponsor Author

LayMui commented Oct 28, 2022

I see.

I found that is another outer field called description

interface BundleData {
id: string,
title: string,
subtitle: string,
acceptLabel:string,
declineLabel: string,
confirmationDialog: {
title: string,
//description: string,
confirmLabel: string,
cancelLabel: string
},
description: string, <------
product: string,
type: string,
lang: string,
country: string[],
documents: Document
}

export default BundleData;

anyway, I get rid of the compilation error by not checking that field that I commented out.

i guess i can leave the .answeredBy(actor) there, right? it does not make any difference without it

 Ensure.that(
                LastResponse.body<Bundle<BundleData>>().data[0].id.answeredBy(actor), matches(/\w+/)
            ),


i got another same issue with another that use the field called description

  | TypeError: rest_1.LastResponse.body(...).data.forecast[0].description.answeredBy is not a function



how can I overcome this ?




  | TypeError: rest_1.LastResponse.body(...).data.forecast[0].description.answeredBy is not a function
-- | --




@viper3400
Copy link
Sponsor Collaborator

viper3400 commented Oct 28, 2022

Can you post the code snippet that produces this error and the interface containing the forecast array your're accessing here.
It's hard to tell what could be the issue, without seeing the code.

Here are some possible reasons for this error.

(For the problem with access the .description I created a separate issue: #1344)

@viper3400
Copy link
Sponsor Collaborator

@LayMui : I copied and pasted your answer in issue #1344 to this issue #1342 as it was requested here. The other issue is a very special situation that I was able to reproduce and like to follow up with Jan Molak separately. I'll delete the comments in the other issue.

I'll follow up your ongoing issues here:


Copy from other issue

interface Forecast<T> {
    status: string,
    errors:  {
        msg: string[],
        errorCode: number
    },
    data: {
        geocode: string
        days: number,
        language: string,
        units: string,
        response: string,
        forecast: T
    }
}

export default Forecast;

interface HourlyForecast {
    cloudCover: number,
    temperature: number,
    qpf: number,
    relativeHumidity: number,
    iconCode: number,
    windDirection: number,
    windSpeed: number,
    qualifierSet: string,
    description: string,
    validTimeUtc: number,
    validTimeLocal: Date,
    expirationTimeUtc: number,
    precipType: string,
    precipChance: number
}

export default HourlyForecast;

the error comes from this line

  Ensure.that(
                LastResponse.body<Forecast<HourlyForecast>>().data.forecast[0].description.answeredBy(actor), matches(/(.*)/)
            ),

@viper3400
Copy link
Sponsor Collaborator

viper3400 commented Oct 29, 2022

Okay, I drilled it down a bit, and you're right, it's the same issue, just a bit covered. I was confused as you access forecast[0] as an array and I'm not sure, if it is one.

But if I we'd access it like this:

Ensure.that(
                    LastResponse.body<Forecast<HourlyForecast>>().data.forecast.location.answeredBy(actor), matches(/(.*)/)
                ),

than we're back at the initial error message: error TS2341: Property 'location' is private and only accessible within class 'Activity'.

I can confirm as well, that is was running in 3.0.0-rc.19. This regression was introduced most likely with this change

So summing up a bit:

  • Initially you raised this issue because there is trouble with the latest axios version
  • This was solved by using the axios version supported by Serenity/JS (0.27.2)
  • Then you ran into a migration error when using LastResponse
  • This is caused by a regression in Serenity/JS between version 3.0.0-rc.19 and 3.0.0-rc.32

Do you agree

@viper3400 viper3400 added enhancement A good idea that should be implemented and removed question awaiting feedback labels Oct 29, 2022
@viper3400 viper3400 changed the title after upgrade to ^3.0.0-rc.32", i got compilation error using CallAnApi.using(axiosInstance), after upgrade to ^3.0.0-rc.32", i got compilation error using CallAnApi.using(axiosInstance) (with axios 1.1.3) Oct 29, 2022
@LayMui
Copy link
Sponsor Author

LayMui commented Oct 29, 2022

yes @viper3400 , i agree this is a separate issue. so I will close this as resolved after change the axios version

@LayMui LayMui closed this as completed Oct 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement A good idea that should be implemented
Projects
None yet
Development

No branches or pull requests

2 participants