Cypress:根据任务结果设置变量

Sim*_*din 5 javascript task promise typescript cypress

我需要从 cypress 场景开始期间发送的电子邮件中检索 url。

等待电子邮件并检索其中的 url 是一项异步任务,因此我创建了一个名为“readMail”的 cypress 插件:它将电子邮件地址作为输入,等待 gmail api 实际收到一封电子邮件,其收件人是此地址,然后阅读邮件并返回解析包含在电子邮件正文中的 url 的承诺。这个过程工作正常,因为来自插件的日志确实正确显示了提取的 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);
});
Run Code Online (Sandbox Code Playgroud)

我可能遗漏了一些关于 cypress 如何处理异步的东西......我尝试了几种不同的东西: cy.wrapcypress-wait-until插件,但找不到任何方法来使这些工作。

实际上,我找到了一种extractedUrl在测试之外声明并开始新测试的方法it('...', () => {...}):然后,extractedUrl实际上在下一个测试开始时具有正确的值,但这并不理想,我想了解原因。谢谢你的帮助 !

JDC*_*L32 6

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);
    });

});

Run Code Online (Sandbox Code Playgroud)

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

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

您也可以尝试cypress-promise,这是一个将 cypress 类承诺对象更改为实际承诺的插件。更多信息:Cypress.io — 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);
    })

});

Run Code Online (Sandbox Code Playgroud)