1

My test is querying a JSON and put value to 'text' variable, but when trying to use the variable I'm getting an error:

cy.type() cannot accept an empty string. You need to actually type something

How can I use the text I got from the query? here is the code:

var text = ''

const WebApiRequests = {
    url : 'https://api.jsonbin.io/v3/b/62e129e3248d43754f074152',
    
    makeRequest : function(method, url, body){
    cy.request({
      method: method,
      url: url,
      body: body
    }).then((response) => {
        text = response.body['record'][0]['team'];
    });
    }
}

const QueryingPage = {
    
    inputNameObject : function(){
        return cy.get('#inputName');
    }
}

describe('Navigate to Querying page', () => {
  it('Visits the Cypress website and clicks on the Querying menu', () => {
    cy.visit('https://example.cypress.io/commands/querying');
    WebApiRequests.makeRequest('GET', WebApiRequests.url, '');
    QueryingPage.inputNameObject().type(text);
    });
  });

Fody
  • 23,754
  • 3
  • 20
  • 37
Ariel
  • 165
  • 1
  • 3
  • 15
  • The error message is pretty clear; it's expecting you to pass a string parameter to that function. The `text` variable in your test is empty, so (assuming `QueryingPage.inputNameObject()` is the same as `cy`) you end up passing an empty string to that function. – Daniel Beck Dec 31 '22 at 18:46
  • You never wait for `makeRequest` to finish – Konrad Dec 31 '22 at 18:48
  • 1
    You're not waiting for the asynchronous call to finish before trying to use its results. See Konrad's link above – Daniel Beck Dec 31 '22 at 18:49
  • Adding a new tag because I know I've answered this before, but can't find it. Thanks for posting a reproducible example. – Fody Dec 31 '22 at 22:24

2 Answers2

2

@Konrad is nearly correct, you need to return both the cy.request() and the result of the following .then().

But unfortunately you can't use async/await on Cypress commands as they do not return Promises, they return Chainer objects.

This is how you can adjust the code

const WebApiRequests = {
  url: "https://api.jsonbin.io/v3/b/62e129e3248d43754f074152",

  makeRequest: function (method, url, body) {
    return cy            // return the Chainable (it's not a promise)
      .request({
        method: method,
        url: url,
        body: body,
      })
      .then((response) => {
        return response.body["record"][0]["team"];   // return the modified response
      });
  },
};

const QueryingPage = {
  inputNameObject: function () {
    return cy.get("#inputName");
  },
};

describe("Navigate to Querying page", () => {
  it("Visits the Cypress website and clicks on the Querying menu", () => {
    cy.visit("https://example.cypress.io/commands/querying");
    WebApiRequests.makeRequest("GET",  WebApiRequests.url,  "")

      // use then to unwrap the Chainable
      .then(text => {
        QueryingPage.inputNameObject().type(text);          // passes
      })
  });
});
Fody
  • 23,754
  • 3
  • 20
  • 37
-1

This code should looks like this:

const WebApiRequests = {
  url: "https://api.jsonbin.io/v3/b/62e129e3248d43754f074152",

  makeRequest: function (method, url, body) {
    // return the promise
    return cy
      .request({
        method: method,
        url: url,
        body: body,
      })
      .then((response) => {
        return response.body["record"][0]["team"];
      });
  },
};

const QueryingPage = {
  inputNameObject: function () {
    return cy.get("#inputName");
  },
};

describe("Navigate to Querying page", () => {
  // make the callback function async
  it("Visits the Cypress website and clicks on the Querying menu", async () => {
    cy.visit("https://example.cypress.io/commands/querying");
    // await for the text
    const text = await WebApiRequests.makeRequest(
      "GET",
      WebApiRequests.url,
      ""
    );
    QueryingPage.inputNameObject().type(text);
  });
});
Konrad
  • 21,590
  • 4
  • 28
  • 64
  • You are confusing thenable and awaitable `await cy.request()` is never going to work, Cypress commands are not awaitable. – Giacomo Dec 31 '22 at 21:34
  • There is no such thing as *thenable*. If something return a promise it can be awaited – Konrad Dec 31 '22 at 21:41
  • 1
    Please read [MDN - Thenables](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#thenables) ***A thenable implements the .then()***. @Ariel kindly provided you a reproducible example, please run your code and see that it throws an error. – Giacomo Dec 31 '22 at 22:07
  • @Giacomo you are right, sorry. I will fix my answer – Konrad Dec 31 '22 at 22:18