cypress: `Cannot read property 'body' of null` error on cy.wait-ing for a request

Current behavior:

When waiting for a route/response, the first request is cancelled (unfortunately no idea why), and the second request (which contains the body, has status 200, etc.) is missed by the wait. This leads to an error: Cannot read property 'body' of null.

Please see the video here: https://dashboard.cypress.io/#/projects/5yp4q1/runs/443/failures/82eb323a-53a8-46a2-86e6-d9a64f4caa87 Here’s a screenshot with the error: 0000000391

Here's the relevant piece of code
function performDocumentViewAction(windowId, documentViewAction, documentIdAliasName) {
  cy.server();
  const layoutAliasName = `visitWindow-layout-${new Date().getTime()}`;
  cy.route('GET', new RegExp(`/rest/api/window/${windowId}/layout`)).as(layoutAliasName);
  const dataAliasName = `visitWindow-data-${new Date().getTime()}`;
  cy.route('GET', new RegExp(`/rest/api/window/${windowId}/[0-9]+$`)).as(dataAliasName);

  documentViewAction();
  cy.wait(`@${layoutAliasName}`, {
    requestTimeout: 20000,
    responseTimeout: 20000,
  })
    .wait(`@${dataAliasName}`, {
      requestTimeout: 20000,
      responseTimeout: 20000,
    })
    .then(xhr => {
      return { documentId: xhr.response.body[0].id };  // here we get the null
    })
    .as(documentIdAliasName);
}

It can be read here: https://github.com/metasfresh/metasfresh-e2e/blob/master/cypress/support/commands/general.js#L251.


After much testing locally i have managed to repro this once, but locally i see no cancelled request, yet the null error still appears: image

Here's the code i have used locally (the only difference is the logging and having to use cy.wrap)
function performDocumentViewAction(windowId, documentViewAction, documentIdAliasName) {
  cy.server();
  const layoutAliasName = `visitWindow-layout-${new Date().getTime()}`;
  cy.route('GET', new RegExp(`/rest/api/window/${windowId}/layout`)).as(layoutAliasName);
  const dataAliasName = `visitWindow-data-${new Date().getTime()}`;
  cy.route('GET', new RegExp(`/rest/api/window/${windowId}/[0-9]+$`)).as(dataAliasName);

  documentViewAction();
  cy.wait(`@${layoutAliasName}`, {
    requestTimeout: 20000,
    responseTimeout: 20000,
  })
    .wait(`@${dataAliasName}`, {
      requestTimeout: 20000,
      responseTimeout: 20000,
    })
    .should(xhr => { // change here
      cy.log('frist!: ' + JSON.stringify(xhr));
    })
    .then(xhr => {
      cy.log('2nd: ' + JSON.stringify(xhr)); // change here
      return cy.wrap({ documentId: xhr.response.body[0].id });
    })
    .as(documentIdAliasName);
}

Here’s the request as logged to console by cypress: image

Here is the xhr from `cy.log`, and it can be seen that the path exists and contains a value (warning: HUGE)
let theXHR = {
  xhr: {
    method: 'GET',
    url: 'https://dev630.metasfresh.com/rest/api/window/123/2156430',
    id: 'xhr739',
  },
  id: 'xhr739',
  url: 'https://dev630.metasfresh.com/rest/api/window/123/2156430',
  method: 'GET',
  status: 200,
  statusMessage: '200 (OK)',
  request: {
    headers: {
      Accept: 'application/json, text/plain, */*',
      'Accept-Language': 'en_US',
    },
    body: null,
  },
  response: {
    headers: {
      date: 'Tue, 06 Aug 2019 06:48:03 GMT',
      'content-encoding': 'gzip',
      server: 'nginx/1.10.3 (Ubuntu)',
      vary: 'Accept-Encoding',
      'access-control-allow-methods': 'POST, GET, OPTIONS, DELETE, PATCH, PUT',
      'content-type': 'application/json;charset=UTF-8',
      'access-control-allow-origin': 'http://localhost:3000',
      'access-control-max-age': '600',
      'transfer-encoding': 'chunked',
      connection: 'keep-alive',
      'access-control-allow-credentials': 'true',
      'access-control-allow-headers': 'x-requested-with, Content-Type, Origin, Accept-Language',
      'x-application-context':
        'metasfresh-webui-api:de.metas.vertical.healthcare.forum_datenaustausch_ch,metasfresh-webui-api:8443',
    },
    body: [
      {
        windowId: '123',
        id: '2156430',
        fieldsByName: {
          ID: {
            field: 'ID',
            value: 2156430,
            widgetType: 'Integer',
          },
          M_FreightCost_ID: {
            field: 'M_FreightCost_ID',
            value: null,
            readonly: false,
            mandatory: false,
            displayed: true,
            lookupValuesStale: true,
            widgetType: 'List',
            validStatus: {
              valid: true,
              initialValue: true,
              fieldName: 'M_FreightCost_ID',
            },
            viewEditorRenderMode: 'always',
          },
          M_Shipper_ID: {
            field: 'M_Shipper_ID',
            value: null,
            readonly: false,
            mandatory: false,
            displayed: true,
            lookupValuesStale: true,
            widgetType: 'List',
            validStatus: {
              valid: true,
              initialValue: true,
              fieldName: 'M_Shipper_ID',
            },
            viewEditorRenderMode: 'always',
          },
          AD_Client_ID: {
            field: 'AD_Client_ID',
            value: {
              key: '1000000',
              caption: 'metasfresh',
            },
            readonly: false,
            mandatory: true,
            displayed: true,
            lookupValuesStale: true,
            widgetType: 'List',
            validStatus: {
              valid: true,
              initialValue: true,
              fieldName: 'AD_Client_ID',
            },
            viewEditorRenderMode: 'always',
          },
          AD_Org_ID: {
            field: 'AD_Org_ID',
            value: {
              key: '1000000',
              caption: 'metasfresh AG',
            },
            readonly: false,
            mandatory: true,
            displayed: true,
            lookupValuesStale: true,
            widgetType: 'List',
            validStatus: {
              valid: true,
              initialValue: true,
              fieldName: 'AD_Org_ID',
            },
            viewEditorRenderMode: 'always',
          },
          Value: {
            field: 'Value',
            value: '1000004',
            readonly: false,
            mandatory: true,
            displayed: true,
            widgetType: 'Text',
            validStatus: {
              valid: true,
              initialValue: true,
              fieldName: 'Value',
            },
            viewEditorRenderMode: 'always',
          },
          Name: {
            field: 'Name',
            value: 'vendor 1565074056375',
            readonly: false,
            mandatory: false,
            displayed: false,
            widgetType: 'Text',
            validStatus: {
              valid: true,
              initialValue: true,
              fieldName: 'Name',
            },
            viewEditorRenderMode: 'always',
          },
          Name2: {
            field: 'Name2',
            value: 'vendor 1565074056375',
            readonly: false,
            mandatory: false,
            displayed: true,
            widgetType: 'Text',
            validStatus: {
              valid: true,
              initialValue: true,
              fieldName: 'Name2',
            },
            viewEditorRenderMode: 'always',
          },
          Description: {
            field: 'Description',
            value: null,
            readonly: false,
            mandatory: false,
            displayed: true,
            widgetType: 'Text',
            validStatus: {
              valid: true,
              initialValue: true,
              fieldName: 'Description',
            },
            viewEditorRenderMode: 'always',
          },
          IsActive: {
            field: 'IsActive',
            value: true,
            readonly: false,
            mandatory: true,
            displayed: true,
            widgetType: 'Switch',
            validStatus: {
              valid: true,
              initialValue: true,
              fieldName: 'IsActive',
            },
            viewEditorRenderMode: 'always',
          },
          IsProducerAllotment: {
            field: 'IsProducerAllotment',
            value: false,
            readonly: false,
            mandatory: false,
            displayed: true,
            widgetType: 'YesNo',
            validStatus: {
              valid: true,
              initialValue: true,
              fieldName: 'IsProducerAllotment',
            },
            viewEditorRenderMode: 'always',
          },
          IsCompany: {
            field: 'IsCompany',
            value: true,
            readonly: false,
            mandatory: false,
            displayed: true,
            widgetType: 'YesNo',
            validStatus: {
              valid: true,
              initialValue: true,
              fieldName: 'IsCompany',
            },
            viewEditorRenderMode: 'always',
          },
          CompanyName: {
            field: 'CompanyName',
            value: 'vendor 1565074056375',
            readonly: false,
            mandatory: true,
            displayed: true,
            widgetType: 'Text',
            validStatus: {
              valid: true,
              initialValue: true,
              fieldName: 'CompanyName',
            },
            viewEditorRenderMode: 'always',
          },
          VATaxID: {
            field: 'VATaxID',
            value: null,
            readonly: false,
            mandatory: false,
            displayed: true,
            widgetType: 'Text',
            validStatus: {
              valid: true,
              initialValue: true,
              fieldName: 'VATaxID',
            },
            viewEditorRenderMode: 'always',
          },
          C_BP_Group_ID: {
            field: 'C_BP_Group_ID',
            value: {
              key: '1000000',
              caption: 'Standard',
            },
            readonly: false,
            mandatory: true,
            displayed: true,
            lookupValuesStale: true,
            widgetType: 'List',
            validStatus: {
              valid: true,
              initialValue: true,
              fieldName: 'C_BP_Group_ID',
            },
            viewEditorRenderMode: 'always',
          },
          AD_Language: {
            field: 'AD_Language',
            value: {
              key: 'en_US',
              caption: 'English (US)',
            },
            readonly: false,
            mandatory: false,
            displayed: true,
            lookupValuesStale: true,
            widgetType: 'List',
            validStatus: {
              valid: true,
              initialValue: true,
              fieldName: 'AD_Language',
            },
            viewEditorRenderMode: 'always',
          },
          IsEdiRecipient: {
            field: 'IsEdiRecipient',
            value: false,
            readonly: false,
            mandatory: true,
            displayed: true,
            widgetType: 'YesNo',
            validStatus: {
              valid: true,
              initialValue: true,
              fieldName: 'IsEdiRecipient',
            },
            viewEditorRenderMode: 'always',
          },
          URL: {
            field: 'URL',
            value: null,
            readonly: false,
            mandatory: false,
            displayed: true,
            widgetType: 'Link',
            validStatus: {
              valid: true,
              initialValue: true,
              fieldName: 'URL',
            },
            viewEditorRenderMode: 'always',
          },
          IsReplicationLookupDefault: {
            field: 'IsReplicationLookupDefault',
            value: false,
            readonly: false,
            mandatory: false,
            displayed: true,
            widgetType: 'YesNo',
            validStatus: {
              valid: true,
              initialValue: true,
              fieldName: 'IsReplicationLookupDefault',
            },
            viewEditorRenderMode: 'always',
          },
          CreditLimitIndicator: {
            field: 'CreditLimitIndicator',
            value: null,
            readonly: true,
            mandatory: false,
            displayed: true,
            widgetType: 'Text',
            validStatus: {
              valid: true,
              initialValue: true,
              fieldName: 'CreditLimitIndicator',
            },
            viewEditorRenderMode: 'never',
          },
          BPartner_Parent_ID: {
            field: 'BPartner_Parent_ID',
            value: null,
            readonly: false,
            mandatory: false,
            displayed: true,
            lookupValuesStale: true,
            widgetType: 'Lookup',
            validStatus: {
              valid: true,
              initialValue: true,
              fieldName: 'BPartner_Parent_ID',
            },
            viewEditorRenderMode: 'always',
          },
          Labels_548674: {
            field: 'Labels_548674',
            value: {
              values: [],
            },
            readonly: false,
            mandatory: false,
            displayed: true,
            lookupValuesStale: true,
            widgetType: 'Labels',
            validStatus: {
              valid: true,
              initialValue: true,
              fieldName: 'Labels_548674',
            },
            viewEditorRenderMode: 'always',
          },
          Labels_554470: {
            field: 'Labels_554470',
            value: {
              values: [],
            },
            readonly: false,
            mandatory: false,
            displayed: true,
            lookupValuesStale: true,
            widgetType: 'Labels',
            validStatus: {
              valid: true,
              initialValue: true,
              fieldName: 'Labels_554470',
            },
            viewEditorRenderMode: 'always',
          },
          V$DocumentSummary: {
            field: 'V$DocumentSummary',
            value: 'vendor 1565074056375 1000004',
            readonly: true,
            mandatory: false,
            displayed: false,
            widgetType: 'Text',
            validStatus: {
              valid: true,
              initialValue: true,
              fieldName: 'V$DocumentSummary',
            },
            viewEditorRenderMode: 'never',
          },
        },
        validStatus: {
          valid: true,
        },
        saveStatus: {
          deleted: false,
          saved: true,
          hasChanges: false,
          error: false,
          reason: 'just loaded',
        },
        includedTabsInfo: {
          'AD_Tab-541096': {
            tabid: 'AD_Tab-541096',
            allowCreateNew: true,
            allowDelete: true,
          },
          'AD_Tab-540739': {
            tabid: 'AD_Tab-540739',
            allowCreateNew: false,
            allowDelete: true,
          },
          'AD_Tab-540829': {
            tabid: 'AD_Tab-540829',
            allowCreateNew: false,
            allowCreateNewReason: 'Tab is readonly',
            allowDelete: false,
            allowDeleteReason: 'Tab is readonly',
          },
          'AD_Tab-226': {
            tabid: 'AD_Tab-226',
            allowCreateNew: true,
            allowDelete: true,
          },
          'AD_Tab-224': {
            tabid: 'AD_Tab-224',
            allowCreateNew: false,
            allowDelete: true,
          },
          'AD_Tab-222': {
            tabid: 'AD_Tab-222',
            allowCreateNew: true,
            allowDelete: true,
          },
          'AD_Tab-223': {
            tabid: 'AD_Tab-223',
            allowCreateNew: false,
            allowDelete: true,
          },
          'AD_Tab-496': {
            tabid: 'AD_Tab-496',
            allowCreateNew: true,
            allowDelete: true,
          },
          'AD_Tab-540737': {
            tabid: 'AD_Tab-540737',
            allowCreateNew: false,
            allowCreateNewReason: 'Tab is readonly',
            allowDelete: false,
            allowDeleteReason: 'Tab is readonly',
          },
          'AD_Tab-541154': {
            tabid: 'AD_Tab-541154',
            allowCreateNew: false,
            allowDelete: true,
          },
          'AD_Tab-541077': {
            tabid: 'AD_Tab-541077',
            allowCreateNew: true,
            allowDelete: true,
          },
          'AD_Tab-541155': {
            tabid: 'AD_Tab-541155',
            allowCreateNew: true,
            allowDelete: true,
          },
          'AD_Tab-540653': {
            tabid: 'AD_Tab-540653',
            allowCreateNew: true,
            allowDelete: true,
          },
          'AD_Tab-540994': {
            tabid: 'AD_Tab-540994',
            allowCreateNew: true,
            allowDelete: true,
          },
        },
        standardActions: ['new', 'advancedEdit', 'email', 'letter', 'delete'],
        websocketEndpoint: '/document/123/2156430',
      },
    ],
  },
  duration: 395,
};

console.log(theXHR.response.body[0].id); // prints: "2156430"

Desired behavior:

Cypress should select the correct request and response.

Versions

Local machine: cypress 3.4.1, os: windows 10 x64, electron Jenkins machine: cypress 3.4.1, os: some linux x64 VPS, electron

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 8
  • Comments: 23 (4 by maintainers)

Commits related to this issue

Most upvoted comments

Hello,

Is there an update about tracking this issue down, as it keeps happening (only when run in jenkins 🙄) and it keeps breaking our tests 😦 ?

Edit: Code was wrong at first but now should be fixed up

Hi @pmattj. So looking through the code. It is possible that xhr could be an array (though I don’t completely see how given the code that you sent). But just to rule it out. Could you do something like this?

	cy.get(alias).then(() => {
		cy.wait(alias, options).then((xhr) => {
                         return cy.log(Array.isArray(xhr)).then(() => xhr);
                 }).then((xhr) => {
	                 const status = xhr.response.body.ok; // <== error here
	                 expect(status).to.equal(true);
		});
	});

If we do that, you should be able to see true or false in the video on the dashboard

image

If it’s not an array, you could try doing this:

cy.log(JSON.stringify(xhr))

to try and output more information on what xhr actually is.