javascript - Cypress : Setting a variable from the result of a task

标签 javascript typescript promise task cypress

我需要从柏树场景开始期间发送的电子邮件中检索 url。
等待电子邮件并检索其中的 url 是一个异步任务,所以我创建了一个名为“readMail”的 cypress 插件:它将电子邮件地址作为输入,等待 gmail api 实际有一封收件人是此地址的电子邮件,然后阅读邮件并返回一个解析包含在电子邮件正文中的 url 的 promise 。此过程运行良好,因为来自插件的日志确实正确显示了提取的 url。
我的问题是做这个extractedUrl可供以后用作参数,例如cy.visit(extractedUrl) : task(...).then(...) 的体外,变量仍未设置。
这是代码:

it('should generate correct email', () => {
    const recipientEmail: string = 'some@email.com';
    const extractedUrl:string = '';

    // ....scenario generating a email to 'some@email.com'.....

    cy.task('readMail', recipientEmail) // plugin logs "https://some.url.com" after a few seconds
    .then((result:any) => {
        extractedUrl= result;
        console.log(result); // logs "https://some.url.com" in the terminal
        cy.log("1:" + extractedUrl); // logs "1:https://some.url.com" in cypress UI
    });
    cy.log("2:"+ extractedUrl); // logs "2:" in cypress UI
    console.log(extractedUrl); // logs nothing
    cy.visit(extractedUrl);
});
我可能遗漏了有关 cypress 如何处理异步的一些信息……我尝试了几种不同的方法:cy.wrapcypress-wait-until插件,但找不到任何方法来使这些工作。
实际上我找到了一种方法是声明 extractedUrl在测试之外并开始新的测试it('...', () => {...}) : 那么,extractedUrl实际上在下一次测试开始时具有正确的值,但这并不理想,我想了解原因。
谢谢你的帮助 !

最佳答案

TL;博士;将整个代码放入 then打回来

it('should generate correct email', () => {
    const recipientEmail: string = 'some@email.com';
    const extractedUrl:string = '';

    // ....scenario generating a email to 'some@email.com'.....
    // plugin logs "https://some.url.com" after a few seconds
    cy.task('readMail', recipientEmail).then((result:any) => {
        extractedUrl= result;
        console.log(result); // logs "https://some.url.com" in the terminal
        cy.log("1:" + extractedUrl); // logs "1:https://some.url.com" in cypress UI
        cy.log("2:"+ extractedUrl); // logs "2:" in cypress UI
        console.log(extractedUrl); // logs nothing
        cy.visit(extractedUrl);
    });

});


与看起来相反, Cypress 命令不返回 promise ,它们返回类似 promise 的对象,并且执行队列由 Cypress 框架处理。这就是在处理 Promise 时一些合乎逻辑的操作不起作用的主要原因。

更多信息:Await-ing Cypress Chains #1417

你也可以试试cypress-promise ,这是一个插件,可以将类似 cypress 的 Promise 对象更改为实际的 Promise。更多信息:Cypress.io — Using async and await by Nicholas Boll

更新#1:

您还可以使用别名来访问该值:

it('should generate correct email', () => {
    const recipientEmail: string = 'some@email.com';
    const extractedUrl:string = '';

    // ....scenario generating a email to 'some@email.com'.....
    // plugin logs "https://some.url.com" after a few seconds
    cy.task('readMail', recipientEmail).then((result:any) => {
        extractedUrl= result;
        cy.wrap(result).as('extractedUrl');
        console.log(result); // logs "https://some.url.com" in the terminal
        cy.log("1:" + extractedUrl); // logs "1:https://some.url.com" in cypress UI
    });

    cy.get('@extractedUrl').then((extractedUrl) => {
        cy.log("2:"+ extractedUrl); // logs "2:" in cypress UI
        console.log(extractedUrl); // logs nothing
        cy.visit(extractedUrl);
    })

});

关于javascript - Cypress : Setting a variable from the result of a task,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59626407/

相关文章:

Typescript - 没有函数的 keyof

javascript - 异步加载在这种情况下不起作用

javascript - 初始化时对 Backbone 集合重新排序

typescript - 从平面配置推断嵌套递归类型

node.js - 如何使用异步/等待从另一个函数访问请求的主体?

javascript - Promise `then` 函数不返回任何内容与函数返回另一个 Promise

Javascript Protractor 比较 promise 总和

javascript - 自动化地缩小大型 TypeScript 应用程序

javascript - 传递通过 Javascript 设置的隐藏表单元素

typescript - 当 T 未定义时如何输入 `K extends keyof T`?