2

I'm new to Cypress, I need in the same test, visit two different URLs and store a value from the first one, to use in the second.

I need to visit this website: https://consulta.guru/gerador-cnpj-gratis click on "Gerar" and copy the generated value to use it on the second website.

I couldn't save this generated value in a variable, and when trying to use the cy.origin function to access another URL, I got this error: "cy.intercept() use is not supported in the cy.origin() callback. Consider using it outside of the callback instead".

But the use of cy.intercept is essential inside this callback. I will put the code I made so far (hides some confidential information).

describe('test', () => {
        
    beforeEach(() => {

        cy.visit('https://consulta.guru/gerador-cnpj-gratis');
        cy.contains('button', 'Gerar').click({force: true});
        cy.intercept('1').as('cnpj');
        cy.wait('@cnpj')
        .its('response.body')
        .should('have.property', 'taxNumbers')
        .then(cnpj => {
        })
    })

    it('login', () => {
        cy.origin('secondurl', () => {
          cy.visit('/admin');
        cy.get('input[name="email"]').type('email');
        cy.intercept('login').as('login');
        cy.contains('button', 'Avançar').click();
        cy.wait('@login')
        .its('response.body')
        .should('have.property', 'generatedCode')
        .then(sixDigitCode => {
        cy.get('.css-k008qs > :nth-child(1)').type(sixDigitCode);
        })
        cy.contains('button', 'Avançar').click();
   
        //teste
        cy.contains('p', 'Grupos').click();
        cy.get('input[name="search"]').type(cnpj);
    })
  })
})
Fody
  • 23,754
  • 3
  • 20
  • 37

3 Answers3

1

The cy.origin() command has some limitations.

You have two options that I can see

Use two tests instead of beforeEach()

Cypress is happy to visit two domains in separate tests, so you can change the beforeEach() into an it().

However, the browser/runner completely reset between domains, so you cannot use and alias, a variable, or a property on the Cypress object to pass the taxNumbers value on to the next test.

You would have to save the taxNumbers to a fixture (or you can save it in a task)

it('gets taxNumber', () => {
  cy.visit("https://consulta.guru/gerador-cnpj-gratis");
  cy.contains("button", "Gerar").click({ force: true });

  cy.intercept("1").as("cnpj");
  cy.wait("@cnpj")
    .its("response.body")
    .should("have.property", "taxNumbers")
    .then((cnpj) => { 

      // save to fixture
      cy.writeFile('./cypress/fixtures/tax-numbers.json', cnpj)  

    });
});

it("login", () => {

  cy.visit('http://example.com')               // 2nd domain (for example)

  cy.fixture('tax-numbers.json').then(taxNumbers => {
    expect(taxNumbers).to.not.eq(undefined)             // ✅ passes
  })
});

Use cy.request() to get the taxNumbers

This is much more efficient - no page loading involved.

Take a look at the devtools network tab, grab the full URL of the file with values and query it using cy.request().

let taxNumbers;

beforeEach(() => {
  cy.request('https://api.nfse.io/Generate/LegalEntities/taxNumber/1')
    .then(response => {
      taxNumbers = response.body.taxNumbers
    })
})

it("login", () => {

  cy.visit('http://example.com')               // 2nd domain (for example)

  expect(taxNumbers).to.not.eq(undefined)          // ✅ passes
});
Fody
  • 23,754
  • 3
  • 20
  • 37
0

You can simply declare a variable before the tests run, inside the describe, then store it in the variable and use it in the second test.

describe('test', () => {
    
let myvar = "";

beforeEach(() => {

    cy.visit('https://consulta.guru/gerador-cnpj-gratis');
    cy.contains('button', 'Gerar').click({force: true});
    cy.intercept('1').as('cnpj');
    cy.wait('@cnpj')
    .its('response.body')
    .should('have.property', 'taxNumbers')
    .then(cnpj => {
         myvar = cnpj;
    })
})

it('login', () => {
    cy.origin('secondurl', () => {
      cy.visit('/admin');
    cy.get('input[name="email"]').type('email');
    cy.intercept('login').as('login');
    cy.contains('button', 'Avançar').click();
    cy.wait('@login')
    .its('response.body')
    .should('have.property', 'generatedCode')
    .then(sixDigitCode => {
    cy.get('.css-k008qs > :nth-child(1)').type(sixDigitCode);
    })
    cy.contains('button', 'Avançar').click();

    //teste
    cy.contains('p', 'Grupos').click();
    cy.get('input[name="search"]').type(cnpj);
})
})
})
Jon A
  • 56
  • 7
  • I've tried this code, but I'm receveing the same error: "cy.intercept() use is not supported in the cy.origin() callback. Consider using it outside of the callback instead" – Vinícius de Lima Cainé Sep 28 '22 at 19:07
  • Sorry, didn't pay attention to the cy.origin command. The first part of the answer from @Fody is what I actually do in my tests. Even if its considered a bad pattern to have a test depending on others, its as simple as it gets. – Jon A Sep 30 '22 at 10:05
0

I tried with the second option, but I don't know where to put this part: "expect (taxnumbers) .to.not.eq (undefined)"

Trying to use the "taxNumbers" to fill a field did not work this way either: cy.get('input[name="searchGroup"]').type(taxNumbers);

The error was: "cy.type() can only accept a string or number. You passed in: [object Object]Learn more "

let taxNumbers;

    beforeEach(() => {
      cy.request('https://api.nfse.io/Generate/LegalEntities/taxNumber/1')
        .then(response => {
          taxNumbers = response.body.taxNumbers
        })
    })
    
    it('login', () => {
      cy.visit('second domain');
      cy.get('input[name="email"]').type('myemail');
      cy.intercept('login').as('login');
      cy.contains('button', 'Avançar').click();
      cy.wait('@login')
        .its('response.body')
        .should('have.property', 'generatedCode')
        .then(sixDigitCode => {
          cy.get('.css-k008qs > :nth-child(1)').type(sixDigitCode);
        })
      cy.contains('button', 'Avançar').click();
    
      //teste
      cy.contains('p', 'Grupos').click();
      cy.get('input[name="searchGroup"]').type(taxNumbers);
    })
  • `expect (taxnumbers) .to.not.eq (undefined)` is just for example, to show the variable `taxNumbers` has been given a value from the `cy.request()` call. – Fody Sep 28 '22 at 21:16
  • But if you look at the format of `response.body.taxNumbers` it's an array with an object, so I am guessing you want to do `cy.get('input[name="searchGroup"]').type(taxNumbers[0].value)`? - it's up to you. – Fody Sep 28 '22 at 21:19
  • I see now. What I need it's just the number generated. In the website when you click in "Gerar" we get a number like this: "28.670.931/0001-16". That's what I need to use in the: `cy.get('input[name="searchGroup"]').type(28.670.931/0001-16)` – Vinícius de Lima Cainé Sep 28 '22 at 21:44