【问题标题】:Cypress : How to get returned value from custom commands ? (Cypress-promise)赛普拉斯:如何从自定义命令中获取返回值? (柏树承诺)
【发布时间】:2019-09-14 18:54:25
【问题描述】:

我正在寻找一种方法来取回自定义赛普拉斯命令返回的返回值。

我目前正在使用 Cypress 和 Cypress-promise lib (https://www.npmjs.com/package/cypress-promise)

目前,结果是: 日志 1=车 1 log2=null

我的错误在哪里?

测试文件:

it('Test 1', async function() {
     const carName = await promisify(cy.set_typeCarName());
     cy.log("log2 = " + carName );
});

模块:

set_typeCarName() {
     let carName = "CAR 1";
     cy.get('#newSiteCityInput').type(carName);
     cy.log("log1 = " + carName);
     return carName;
};

Cypress.Commands.add('set_typeCarName',() => {
    webnewsite.set_typeCarName();
});

【问题讨论】:

  • 你解决了吗?请您与我们分享解决方案吗?
  • @wawanopoulos,如果你觉得可以的话,你能把它标记为已解决吗?

标签: javascript promise cypress


【解决方案1】:

该命令是否缺少return 语句?

Cypress.Commands.add('set_typeCarName',() => {
  return webnewsite.set_typeCarName(); // I added the initial `return`
});

【讨论】:

  • 不工作了,赛普拉斯不返回自定义命令的结果。并在自定义命令中使用 return 时抛出警告。
【解决方案2】:

我想这就是你想要的:

测试文件

            cy.set_typeCarName()
                .then((returned_value) => {
                    cy.log("log2 = " + returned_value)
                })
            });

模块

    Cypress.Commands.add('set_typeCarName',() => {
            let carName = "CAR 1";
            cy.get('#newSiteCityInput').type(carName);
            cy.log("log1 = " + carName);
            return carName;
    });

【讨论】:

  • 这似乎是更正确的答案。无需按照@8888 的建议包装返回值。它可能已经被 Cypress 自动包装了。
  • 这将抛出CypressError: Cypress detected that you invoked one or more cy commands in a custom command but returned a different value.。使用换行,或在then() 中返回,根据您的命令逻辑
  • 在这里强烈反对@Kuranes。正如@Artur 所说,它需要被包装。赛普拉斯错误解释说它曾经在早期版本中自动包装,但现在不再是:In previous versions of Cypress we automatically detected this and forced the cy commands to be returned. To make things less magical and clearer, we are now throwing an error.
  • 感谢您的更新!我无法删除我的赞成票,但我也会赞成@8888 的回答。为过时的信息道歉。
【解决方案3】:

为此,我使用wrap() 返回一个包含我想要返回的值的Chainable

模块

function foo() {
  return cy.wrap('foo');
}

Cypress.Commands.add('foo', foo);

测试文件

cy.foo().then(value => console.log(value)); // foo

由于wrap() 返回一个Cypress.Chainable,我们可以在我们的命令上调用.then()。传递给 wrap() 的任何内容都将交给下一个命令。

另请参阅:Cypress wrap() documentation

【讨论】:

  • cypress 改造 Javascript 的方式令人作呕。
【解决方案4】:

赛普拉斯引入了一种编写代码而不是返回值的新方法,即使用别名。 https://docs.cypress.io/guides/core-concepts/variables-and-aliases.html#Closures

正常的写代码方式

async function compute(){
const value = await (asynchronous function);
return value;
}

const x = await compute(); // #a
console.log(x);            // #b

如何在 Cypress 中执行此操作,因为我们不能在 cypress 中使用 async/await

function() compute{
  cy.get('p#text').then(p => {
    const text = p.textContent;
    cy.wrap(text).as('pText');
    //even if we return text from here, it will not be accessible anywhere

  });
}

compute();    // #a
cy.get('@pText').then(text => {
  console.log(text);  // #b
}

关键是为该值设置别名,然后在下一个命令中使用它

因为

赛普拉斯首先运行整个代码并将命令放入队列
一次代码在队列中,队列中的下一条命令只有在当前命令的所有回调完成后才会运行,因此我们可以使用上面的代码模式。

【讨论】:

  • 我喜欢这个解决方案解决异步处理问题。我在实现中使用了命令,但发现我仍然需要一些别名处理,所以我从 then 获取一些东西,并通过同一命令中的别名返回变异版本
【解决方案5】:

如何使用返回值的一个例子
注意:此方法采用一个数值,例如 3445.55 并将其设为 3,445.55

Commands.js中的方法

Cypress.Commands.add('getValueWithComma', (num) => {
      const n = String(num),
        p = n.indexOf('.');
      return n.replace(/\d(?=(?:\d{3})+(?:\.|$))/g, (m, i) =>
        p < 0 || i < p ? `${m},` : m,
      );
    });

如何在.spec文件中调用

 cy.getValueWithComma(pass_value).then((returned_value) => {
              cy.log(' Returned value is   = ', returned_value);
            });

【讨论】:

  • 不工作了,赛普拉斯不返回自定义命令的结果。并在自定义命令中使用 return 时抛出警告。
【解决方案6】:

使用您的代码回答

Cypress.Commands.add('set_typeCarName',() => {
    return cy.wrap(webnewsite.set_typeCarName()); //return the wrap and use in chain
});

function set_typeCarName() {
 let carName = "CAR 1";
 cy.get('#newSiteCityInput').type(carName);
 cy.log("log1 = " + carName);
 return carName;
};

测试

it('Test 1', async function() {
     cy.set_typeCarName().then(carName => {
         cy.log("log2 = " + carName );
     }
);
     

【讨论】:

    【解决方案7】:

    PLS 记住 cy 命令不是 Promise。您不能自信地使用async/await 并期望它们在cy 命令中正常工作。您可以将Promiseawait 关键字一起使用。并在 w3schools 上查找更多信息:https://www.w3schools.com/js/js_promise.asp,这对我有很大帮助

    • 以下最终在柏树为我工作
    // {bidderCreationRequest} was declared earlier
    
    function createBidderObject() {
      const bidderJson = {};
      await new Promise((generateBidderObject) => {
        cy.request(bidderCreationRequest).then((bidderCreationResp) => {
          bidderJson.id = bidderDMCreationResp.body.id;
    
          generateBidderObject(bidderJson);
        });
      });
    
      return bidderJson.id
    }
    
    createBidderObject(); // returns the id of the recently created bidder instead of undefined/null
    

    你也可以使用https://github.com/NicholasBoll/cypress-promise#readme,因为cy命令又不是Promises。因此,如果您使用 async/await 并使用本机 Promise 函数或提到的插件,那么您会很幸运

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多