使用TypeScript时添加自定义的Cypress命令

时间:2019-07-28 12:09:40

标签: typescript cypress

我正在尝试创建一个新的cypress命令,该命令允许我使用formData发布文件,因为cy.request还不支持formData

我正在将request-promise-native本身用于POST

首先,在我的commands.ts中,我像这样扩展Cypress.Chainable interface

declare global {
  namespace Cypress {
    interface Chainable<Subject = any> {
      postFormData(
        url: string, 
        formData: FormData, 
        token: string): Chainable<FullResponse>
    }
  }
}

FullResponserequest-promise-native的响应类型定义。

我的postFormData函数如下所示:

function postFormData(
  url,
  formData,
  token
): Cypress.Chainable<FullResponse> {  // this is line 52
  const response: FullResponse = await post(url, {
    auth: { bearer: token },
    formData
  })
  return cy.wrap(response) // this is line 58
}

最后,我正在注册新命令:

Cypress.Commands.add('postFormData', postFormData)

在我的test.ts中,我这样调用该命令:

const response = cy.postFormData(
  url,
  formData,
  accessToken)
expect(response.statusCode).to.equal(202)

但是,tsc给了我这些错误:

commands.ts:52:4 -  error TS1064: The return type of an async function or method must be the global Promise<T> type.

commands.ts:58:3 - error TS1058: The return type of an async function must either be a valid promise or must not contain a callable 'then' member.

cy.wrap返回一个Chainable而不返回一个Promise,那么我该如何解决呢?

1 个答案:

答案 0 :(得分:0)

这是一个可能的解决方案

import { post, FullResponse } from 'request-promise-native'

declare global {
  namespace Cypress {
    interface Chainable<Subject = any> {
      postFormData(
        url: string, 
        formData: FormData, 
        token: string): Chainable<FullResponse>
    }
  }
}

function postFormData(url, formData, token): Cypress.Chainable<any> {
  return cy.wrap(
    post(url, {
      auth: { bearer: token },
      formData
    })
  )

Cypress.Commands.add('postFormData', postFormData)

正确的用法是:

cy.postFormData(
  url,
  formData,
  accessToken)
  .then((response) => {
    expect(response.statusCode).to.equal(202)
  })

更新

request is in maintainance mode的形式存在issue with browsersformData,这是使用axios的解决方案:

import axios, { AxiosResponse } from 'axios'

declare global {
  namespace Cypress {
    interface Chainable<Subject = any> {
      postFormData(
        url: string,
        formData: FormData,
        token: string
      ): Chainable<AxiosResponse>
    }
  }
}

function postFormData(url, formData, token): Cypress.Chainable<any> {
  return cy.wrap(
    axios(url, {
      method: 'post',
      url,
      data: formData,
      headers: {
        Authorization: `Bearer ${token}`,
        'Content-Type': 'multipart/form-data'
      }
    })
  )
}

Cypress.Commands.add('postFormData', postFormData)

用法:

cy.postFormData(
  url,
  formData,
  accessToken)
  .then((response) => {
    expect(response.status).to.equal(202)
  })