如何在Cypress中从一个测试(it)分享变量到另一个测试,当域名不同?

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

How to share a variable in Cypress from one test (it) to another when the domains are different?

问题

如何在不同域之间从一个测试中共享变量到另一个测试?

我已经尝试了无数种方法,包括别名(Alias)、闭包(Closure)、环境变量(Environment Variable)、本地存储(Local Storage),甚至使用事件监听器(Event Listener),但在执行下一个测试时,这些变量都会从内存中清除。

关键问题是,我需要获取Web应用程序中打开协议的ID,然后转到另一个域中的后台验证该协议是否真的已打开。

以下是我放弃后的最新版本代码:

/// <reference types="cypress" />

describe("Test opening a protocol in the contact us", () => {
    it("Should access ContactUs, open a protocol, and then validate the correct opening in the back office", () => {
        cy.visit(`${Cypress.env('CONTACT_US_URL')}`)
        cy.get("#CreateNewRequestButton").click()
        
        cy.get('#CpfCnpjInput').type("99999999999")
        cy.get('#EmailInput').type("email@email.com")
        cy.get('#PhoneNumberInput').type("99999999999")
        cy.get('#SubjectInput').type("Test subject")
        cy.get('#DescriptionInput').type("This is a very detailed description, trust me")
        cy.get('#SendButton').click()

        cy.get('#CallNumberSpan').should('contain', 'Call number')
        cy.get('#CallNumberDiv').then($div => {
            const call_number = $div.text().split(' ')[3].replace(/^#/, "");
            // cy.wrap(call_number).as("myVariable");

            // Send the alias value to the second domain using postMessage
            cy.window().then((win) => {
                win.postMessage({ type: "aliasValue", value: call_number }, "*");
            });
            // Cypress.env('call_number', call_number);
            // cy.log("call_number - " + Cypress.env('call_number'));
            // cy.window().then(win => {
            // win.localStorage.setItem('call_number', call_number);
            // });
        });

        // cy.get('#CallNumberDiv').invoke('text').as('myVariable')
        // // ($div => {
        // //     const call_number = $div.text().split(' ')[3].replace(/^#/, "");
        // //     cy.wrap(call_number).as("myVariable");

        // // Send the alias value to the second domain using postMessage
        // cy.window().then((win) => {
        //     win.postMessage({ type: "aliasValue", value: cy.get("@myVariable") }, "*");
        // });
        // //     // Cypress.env('call_number', call_number);
        // //     // cy.log("call_number - " + Cypress.env('call_number'));
        // //     // cy.window().then(win => {
        // //     // win.localStorage.setItem('call_number', call_number);
        // //     // });
        // // });

    });

    it("Should access Connect and validate the correct protocol opening", () => {
        cy.visit(`${Cypress.env('URL')}`);

        // Receive the message containing the value of the alias sent by the first domain
        cy.window().then((win) => {
            win.addEventListener("message", (event) => {
                const message = event.data;

                // Check if the message contains the value of the alias
                if (message.type === "aliasValue") {
                    const aliasValue = message.value;
                    cy.wrap(aliasValue).as("mySharedAlias");
                }
            });
        });

        // Do something with the shared alias in the second domain
        cy.get("@mySharedAlias").then((value) => {
            // Do something with the value of the shared alias
            cy.log("Value of the shared alias:", value);
            cy.login();
            cy.visit(`${Cypress.env('URL')}/ticket-container/${Cypress.env('value')}`)
        });

    });

})

请注意,我已经注释掉了一些部分,这些部分是我尝试但未成功的共享变量的方法。希望这可以帮助你解决问题。

英文:

How to share a variable from one test (it) to another when the domains are different?
I've tried in countless ways, with Alias, Closure, Environment Variable, Local Storage, even with Event Listener, but when the next test is executed, these variables are cleared from memory.

The point is that I need to obtain the ID of an open protocol in a Web application, go to the backoffice that is in another domain to validate if that protocol was really opened.
Here is the last version after giving up...

/// &lt;reference types=&quot;cypress&quot; /&gt;
describe(&quot;Testar abertura de protocolo no fale conosco&quot;, () =&gt; {
it(&quot;Deve acessar o FaleConosco, abrir um protocolo e depois validar no backoffice a abertura correta do mesmo&quot;, () =&gt; {
cy.visit(`${Cypress.env(&#39;FALE_CONOSCO_URL&#39;)}`)
cy.get(&quot;#BotaoCriarNovoChamado&quot;).click()
cy.get(&#39;#InputLabelCpfCnpj&#39;).type(&quot;99999999999&quot;)
cy.get(&#39;#InputLabelEmail&#39;).type(&quot;email@email.com&quot;)
cy.get(&#39;#InputLabelTelefone&#39;).type(&quot;99999999999&quot;)
cy.get(&#39;#InputLabelAssunto&#39;).type(&quot;Assunto de teste&quot;)
cy.get(&#39;#InputLabelDescricao&#39;).type(&quot;Essa aqui e uma descri&#231;&#227;o bem detalhada, confia&quot;)
cy.get(&#39;#BotaoEnviar&#39;).click()
cy.get(&#39;#spanNumeroDoChamado&#39;).should(&#39;contain&#39;, &#39;N&#250;mero do chamado&#39;)
cy.get(&#39;#divNumeroDoChamado&#39;).then($div =&gt; {
const numero_do_chamado = $div.text().split(&#39; &#39;)[3].replace(/^#/, &quot;&quot;);
// cy.wrap(numero_do_chamado).as(&quot;minhaVariavel&quot;);
// Enviar o valor do alias para o segundo dom&#237;nio usando postMessage
cy.window().then((win) =&gt; {
win.postMessage({ type: &quot;aliasValue&quot;, value: numero_do_chamado }, &quot;*&quot;);
});
// Cypress.env(&#39;numero_do_chamado&#39;, numero_do_chamado);
// cy.log(&quot;numero_do_chamado  -  &quot; + Cypress.env(&#39;numero_do_chamado&#39;));
// cy.window().then(win =&gt; {
// win.localStorage.setItem(&#39;numero_do_chamado&#39;, numero_do_chamado);
// });
});
// cy.get(&#39;#divNumeroDoChamado&#39;).invoke(&quot;text&quot;).as(&quot;minhaVariavel&quot;)
// // ($div =&gt; {
// //     const numero_do_chamado = $div.text().split(&#39; &#39;)[3].replace(/^#/, &quot;&quot;);
// //     cy.wrap(numero_do_chamado).as(&quot;minhaVariavel&quot;);
// // Enviar o valor do alias para o segundo dom&#237;nio usando postMessage
// cy.window().then((win) =&gt; {
//     win.postMessage({ type: &quot;aliasValue&quot;, value: cy.get(&quot;@minhaVariavel&quot;) }, &quot;*&quot;);
// });
// //     // Cypress.env(&#39;numero_do_chamado&#39;, numero_do_chamado);
// //     // cy.log(&quot;numero_do_chamado  -  &quot; + Cypress.env(&#39;numero_do_chamado&#39;));
// //     // cy.window().then(win =&gt; {
// //     // win.localStorage.setItem(&#39;numero_do_chamado&#39;, numero_do_chamado);
// //     // });
// // });
});
it(&quot;Deve acessar o Conecta e validar a abertura correta protocolo&quot;, () =&gt; {
cy.visit(`${Cypress.env(&#39;URL&#39;)}`);
// Receber a mensagem contendo o valor do alias enviado pelo primeiro dom&#237;nio
cy.window().then((win) =&gt; {
win.addEventListener(&quot;message&quot;, (event) =&gt; {
const message = event.data;
// Verificar se a mensagem cont&#233;m o valor do alias
if (message.type === &quot;aliasValue&quot;) {
const aliasValue = message.value;
cy.wrap(aliasValue).as(&quot;meuAliasCompartilhado&quot;);
}
});
});
// Fazer algo com o alias compartilhado no segundo dom&#237;nio
cy.get(&quot;@meuAliasCompartilhado&quot;).then((valor) =&gt; {
// Fa&#231;a algo com o valor do alias compartilhado
cy.log(&quot;Valor do alias compartilhado:&quot;, valor);
cy.login();
cy.visit(`${Cypress.env(&#39;URL&#39;)}/ticket-container/${Cypress.env(&#39;valor&#39;)}`)
});
});
})

答案1

得分: 5

当测试运行器更改域时,整个浏览器对象将被重置,因此写入浏览器内存的任何变量都将丢失

  • 闭包变量
  • 别名
  • 环境变量(Cypress.env)。

这将使你只能使用fixture(磁盘存储)或与任务相关的伪数据存储(请参阅 bahmutov/cypress-data-session)。

对于 fixture,代码如下:

it("Deve acessar o FaleConosco...", () => {
  cy.visit(`${Cypress.env('FALE_CONOSCO_URL')}`)
  ...
    const numero_do_chamado = $div.text().split(' ')[3].replace(/^#/, "")
    cy.writeFile('cypress/fixtures/numero_do_chamado.json', numero_do_chamado)
    ...
})

it("Deve acessar o Conecta...", () => {
  cy.visit(`${Cypress.env('URL')}`)
  ...
  const numero_do_chamado = cy.readFile('cypress/fixtures/numero_do_chamado.json')
  ...
})

不要使用 cy.fixture() 命令,因为它在内部涉及缓存。这对于您当前的情况没有问题,但当您的测试模式发生更改时,可能会导致意外错误。

英文:

When the test runner changes domains the whole browser object is reset, so any variables written to browser memory are lost

  • closure variables
  • aliases
  • env var (Cypress.env).

That leaves you with fixture (disk storage) or task-related pseudo data store (see bahmutov/cypress-data-session).

For fixture, the code would be

it(&quot;Deve acessar o FaleConosco...&quot;, () =&gt; {
  cy.visit(`${Cypress.env(&#39;FALE_CONOSCO_URL&#39;)}`)
  ...
    const numero_do_chamado = $div.text().split(&#39; &#39;)[3].replace(/^#/, &quot;&quot;)
    cy.writeFile(&#39;cypress/fixtures/numero_do_chamado.json&#39;, numero_do_chamado)
    ...
})

it(&quot;Deve acessar o Conecta...&quot;, () =&gt; {
  cy.visit(`${Cypress.env(&#39;URL&#39;)}`)
  ...
  const numero_do_chamado = cy.readFile(&#39;cypress/fixtures/numero_do_chamado.json&#39;)
  ...
})

Don't use cy.fixture() command as there is caching involved internally. Not a problem for your current scenario, but may cause unexpected errors when your test pattern changes.

答案2

得分: 0

我假设你正在使用当前版本的Cypress(12版本)。请尝试关闭测试隔离:

describe('workflow', { testIsolation: false }, () => {
  ...
})

如果这解决了你的问题,请提供反馈。

英文:

I assume you use current, 12, version of Cypress. Please try turning testIsolation off:

describe(&#39;workflow&#39;, { testIsolation: false }, () =&gt; {
...
})

and give feedback if this solved your issue.

huangapple
  • 本文由 发表于 2023年6月1日 20:22:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76381814.html
匿名

发表评论

匿名网友

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

确定