如何使用badeball/cypress-cucumber-preprocessor库使转换工作?

huangapple go评论70阅读模式
英文:

How do I make transformation work using badeball/cypress-cucumber-preprocessor library?

问题

I've spent many hours on it already and it doesn't work as intended. Here's one of attempts to make it clear:

// something.feature
Feature: asdf
  Scenario: asdf asdf
    # any of steps below called here gives the same error
    # When something "second parameter"
    When something option1 "second parameter"
    # When something secondOption "second parameter"
// steps.ts
When('something {OptionType} {string}', (
  firstParameter: OptionType, 
  secondParameter: string) => {
    // todo
});
// transformations.ts
import { defineParameterType } from '@badeball/cypress-cucumber-preprocessor';

export enum OptionType {
  defaultOption,
  option1,
  secondOption,
  blablabla,
}

defineParameterType({
  name: 'OptionType',
  regexp: /^(option1|secondOption|blablabla)?$/,
  transformer: (value: string) => {
    let result = OptionType.defaultOption;
    switch(value) {
      case "":
        result = OptionType.defaultOption;
        break;
      case "option1":
        result = OptionType.option1;
        break;
      case "secondOption":
        result = OptionType.secondOption;
        break;
      case "blablabla":
        result = OptionType.blablabla;
        break;
      default:
        throw new Error("No suitable option");
    }
    return result;
  },
});

So what I want is that I want first parameter to be optional so that if it's called as the first call in the feature file firstParameter has value OptionType.defaultOption and if there's some other option, then it has the corresponding enum value. I want to change the second parameter to a class object later, but I think that if I accomplish this enum thing - I'll handle the class as well.

All my attempts failed so far. Right now it says that the step is missing implementation. When I tried to change {OptionType} to (.*) in the step definition - it gives the same error.

Any ideas on what's wrong here?

I'm using these versions:

  • "@angular/common": "15.1.1",
  • "@nrwl/cypress": "15.5.2",
  • "@badeball/cypress-cucumber-preprocessor": "^15.1.4",
  • "nx": "15.5.2".

Also, the path is not the default cypress/.... It's placed inside a separate app. Not sure, but probably that could influence something as well? I've imported step definitions and transformations so they are definitely not missing right now for Cypress. But probably something else does?

Here's a documentation on this topic, but it seems that it's missing a more complete example or it's not designed to be used with Nx and in a different folder than the default cypress folder or everything above.

Also, please note that "cypress-cucumber-preprocessor" library is an old outdated one. Currently, ownership has changed, and the latest up-to-date library is "badeball/cypress-cucumber-preprocessor". So when you write an answer, please make sure it's not referring to the old one because it might not work anymore.

P.S. This is not 100% actual code from my project. I've changed things to make sure I don't violate NDA.

英文:

I've spent many hours on it already and it doesn't work as intended. Here's one of attempts to make it clear:

<!-- language: js -->

// something.feature
Feature: asdf
  Scenario: asdf asdf
    # any of steps below called here gives the same error
    # When something &quot;second parameter&quot;
    When something option1 &quot;second parameter&quot;
    # When something secondOption &quot;second parameter&quot;

<!-- language: js -->

// steps.ts
When(&#39;something {OptionType} {string}&#39;, (
  firstParameter: OptionType, 
  secondParameter: string) =&gt; {
    // todo
});

<!-- language: js -->

// transformations.ts
import { defineParameterType } from &#39;@badeball/cypress-cucumber-preprocessor&#39;;

export enum OptionType {
  defaultOption,
  option1,
  secondOption,
  blablabla,
}

defineParameterType({
  name: &#39;OptionType&#39;,
  regexp: /^(option1|secondOption|blablabla)?$/,
  transformer: (value: string) =&gt; {
    let result = OptionType.defaultOption;
    switch(value) {
      case &quot;&quot;:
        result = OptionType.defaultOption;
        break;
      case &quot;option1&quot;:
        result = OptionType.option1;
        break;
      case &quot;secondOption&quot;:
        result = OptionType.secondOption;
        break;
      case &quot;blablabla&quot;:
        result = OptionType.blablabla;
        break;
      default:
        throw new Error(&quot;No suitable option&quot;);
    }
    return result;
  },
});

So what I want is that I want first parameter to be optional so that if it's called as first call in feature file firstParameter has value OptionType.defaultOption and if there's some other option, then it has corresponding enum value.
I want to change second parameter to a class object later but I think that if I accomplish this enum thing - I'll handle class as well.

All my attempts failed so far. Right now it says that the step is missing implementation. When I tried to change {OptionType} to (.*) in the step definition - it gives the same error.

Any ideas on what's wrong here?

I'm using these versions:
"@angular/common": "15.1.1",
"@nrwl/cypress": "15.5.2",
"@badeball/cypress-cucumber-preprocessor": "^15.1.4",
"nx": "15.5.2".

Also path is not default cypress/.... It's placed inside a separate app. Not sure, but probably that could influence something as well?
I've imported step definitions and transformations so they are definitely not missing right now for cypress. But probably something else does?

Here's a documentation on this topic but it seems that it's missing a more complete example or it's not designed to be used with nx and in a different folder then default cypress folder or everything above.

Also please note that "cypress-cucumber-preprocessor" library is an old outdated one. Currently ownership has changed and latest up to date library is "badeball/cypress-cucumber-preprocessor". So when you write an answer please make sure it's not referring to the old one because it might not work any more.

P.S. This is not 100% actual code from my project. I've changed things to make sure I don't violate NDA.

答案1

得分: 2

我认为defineParameterType 在这里帮助有限。 "name" 参数似乎只对应一个参数名称,我看不到它解决两个参数的情况。

错误看起来是由于"When something "second parameter"" 只有一个参数,并且在 steps.ts 中没有匹配的模式。

所以,你可以添加一个"overload" 步骤定义

steps.ts

// 匹配第一个功能步骤
When('something {string}', (secondParameter: string) => {
  handleOptionType(OptionType.defaultOption, secondParameter)
}

// 匹配其他功能步骤
When('something {OptionType} {string}', (firstParameter: OptionType, secondParameter: string) => {
  handleOptionType(firstParameter, secondParameter)
})

function handleOptionType(firstParameter: OptionType, secondParameter: string) {
  // todo
}
英文:

I don't think defineParameterType can do much for you here. The "name" parameter seems to correspond to one parameter name only, I can't see it resolving two parameters.

The error looks due to When something &quot;second parameter&quot; having just one parameter, and there is no matching pattern in steps.ts.

So, you could add an "overload" step definition

steps.ts

// match first feature step
When(&#39;something {string}&#39;, (secondParameter: string) =&gt; {
  handleOptionType(OptionType.defaultOption, secondParameter)
}

// match other feature steps
When(&#39;something {OptionType} {string}&#39;, (firstParameter: OptionType, secondParameter: string) =&gt; {
  handleOptionType(firstParameter, secondParameter)
})

function handleOptionType(firstParameter: OptionType, secondParameter: string) {
  // todo
}

答案2

得分: 0

问题的根本原因是在defineParameterType调用中的OptionType正则表达式中包含^$字符。删除它们可以使一切正常工作。

在不指定第一个参数的情况下调用该步骤仍然需要编辑(类似于重载该步骤或从步骤定义字符串中删除1个空格,然后在OptionType正则表达式的每个选项中添加一个空格),但它开始正常工作。

我最佳的猜测是When函数的第一个参数中的正则表达式中的"{OptionType}"部分被替换为"OptionType"正则表达式,结果就是这个正则表达式:

something ^(option1|secondOption|blablabla)?$ ".*"

因此,由于正则表达式中间包含字符"^"和"$",没有任何字符串能够匹配它。这是因为这些字符表示字符串的开头和结尾,它们被放在了中间。

所以要使正则表达式正常工作,结果正则表达式必须是这样的:

something (option1|secondOption|blablabla)? ".*"

并且defineParameterType的正则表达式参数必须是这样的:

regexp: /(option1|secondOption|blablabla)?/,
英文:

It turned out that the root cause of this error were ^ and $ characters in the regex of OptionType in the defineParameterType call. Deleting them makes everything work.

Call of the step without specifying the first parameter still requires editing (like overloading of the step or removing 1 space from step definition string and adding a space instead to every option in OptionType regex) but it starts working.

My best guess is that "{OptionType}" part of the regex that goes as first parameter to When function is replaced by OptionType regex and as result there is this regex:

something ^(option1|secondOption|blablabla)?$ &quot;.*&quot;

So evantually since there are characters "^" and "$" in the middle of a regular expression - there's no way any string would match that. It's because those characters mean start and end of the string and they are placed in the middle.

So the result regex has to be like this to work:

something (option1|secondOption|blablabla)? &quot;.*&quot;

and regex parameter of defineParameterType has to be like this:

regexp: /(option1|secondOption|blablabla)?/,

huangapple
  • 本文由 发表于 2023年3月4日 06:46:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/75632478.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定