cypress-io / cypress

Fast, easy and reliable testing for anything that runs in a browser.
https://cypress.io
MIT License
47.03k stars 3.19k forks source link

How can we validate non xhr network request or img type request(applicable for analytics tag) #5047

Closed suvendupanja closed 3 years ago

suvendupanja commented 5 years ago

For my testing I want to validate all the analytics tag using cypress. But When i lunch an website different analytics tags are fired. i would like to validate the outgoing request for different analytics. These sorts of tags are available in network tab img section. Can anyone provide me a sample code to check that ..

I have used the following code which is not working :

describe('test ', function () {
      it('test analytics tag ', () => {
        cy.server();

         cy.route({
             url: /b\/ss/
         }).as('getURL');

         cy.visit("www.example.com");

         cy.wait('@getURL').its("url").should("include", "b");
          })

This is not able to intercept the rerquest for analytics tag

mpahuja commented 5 years ago

if its a non-xhr request, e.g. being served from a CDN or something, then it must be attributing to an element. You should get that element and check for the url. Something described here: https://docs.cypress.io/api/commands/should.html#Method-and-Value

suvendupanja commented 5 years ago

if its a non-xhr request, e.g. being served from a CDN or something, then it must be attributing to an element. You should get that element and check for the url. Something described here: https://docs.cypress.io/api/commands/should.html#Method-and-Value

That outgoing request is not attributed to any element in the webpage. In that can how can we capture that outgoing request captured a img.

mpahuja commented 5 years ago

can you please clarify if you are trying to verify an image request on a webpage or are you trying to validate an analytics event? if the image you are trying to validate comes from a different origin then cy.route may not work.

Can you please site an example of a public webpage that can be used to understand what you are trying to validate?

suvendupanja commented 5 years ago

I am trying to verify the image request. You can refer one of Australia's public internet broadband website https://www.telstra.com.au/ the requirement to validate the adobe tags. We can get the adobe tag request by following ways: Go to network tab in dev tool and filter with b/ss. I would like to validate the some parts of query string parameter of body of the request.

The body of the request is having some of the adobe analytics values

mpahuja commented 5 years ago

This might be close to what you are looking for: https://github.com/cypress-io/cypress-example-recipes/tree/master/examples/stubbing-spying__google-analytics

RichieRunner commented 5 years ago

@suvendupanja have you figured it out? I'm looking to do the same.

suvendupanja commented 5 years ago

Hi Richie,

I have figure out in different way. When I land into a webpage I get all the network request by using window.performance.getEntries(). Store into an array. After that put an assertion what analytics tag I am looking for. Hope this will help.

suvendupanja commented 5 years ago

The option mpahuja provide that is also but I feel If I get all entries in a single go then it will be easy and less coding is required.

RichieRunner commented 5 years ago

Hi Richie,

I have figure out in different way. When I land into a webpage I get all the network request by using window.performance.getEntries(). Store into an array. After that put an assertion what analytics tag I am looking for. Hope this will help.

@suvendupanja hmm interesting, but i'm noticing that in the cypress test runner console. your webpage is actually embedded in its own iframe, so the network request calls that I want to listen to (img type) are not reachable through the parent page.

image

suvendupanja commented 5 years ago

I can see all the request including img (which are mostly analytics tag). Can you give me an example website?

RichieRunner commented 5 years ago

That is odd...are you using cypress open or cypress run? I do see all of my tag requests coming through too in the Network Request tag, but I am having trouble targetting/spying on them.

The product I'm using (Adobe) isn't GTM, but it's the same concept. There's a script tag on my web page that loads in the javascript resource, which then exposes a new function onto the global window object. In my code, I am executing this function which then sends out a network request of type img/gif.

But as we find out in the documentation for cy.route(),

Requests using the Fetch API and other types of network requests like page loads and <script> tags will not be intercepted or visible in the Command Log.

https://docs.cypress.io/api/commands/route.html#Syntax

suvendupanja commented 5 years ago

Hi Richie,

I have implemented in the following ways

visit the site then within window object call window.performance.entries() and store it into a array/object. please do not use cy.route. My understanding is that cy.route only capture xhr request. but window.performance.entries() this gives you all request.

Then can filter which is relevant for you and asset accordingly. I am not sure is there any better way we can do but it works for me so far

ccodecamp commented 5 years ago

Hi @suvendupanja , I am having the same issue as @RichieRunner . In the cypress test runner console I can see all the requests coming through except for the img tag(adobe analytics). Were you able to see the img requests only for cypress run ?

suvendupanja commented 5 years ago

In the network tab you can the request. You can filter thru adobe filter b/ss. if you wan to access programatically you can use the following code

cy.visit("Pagename")
cy.window().then((win) => {
                var networkrequests = win.performance.getEntries().map(r => r.name);
               //previous step will give you array of all the Network request. 
              // You can filter the network request based on the you filter criteria (like Adobe b/ss string 
                  should be thet for GA : google-analytics etc)

})

Withing window you can filter the which request is adobe by name. You can put assertion on top it.

ccodecamp commented 5 years ago

Thanks @suvendupanja , although I am unable to see any adobe analytics requests coming through in cypress test runner console. The window.performance.entries() call returns all the requests except the analytics one. In the google chrome/edge console the window.performance.entries() call returns all the requests including the img requests.

suvendupanja commented 5 years ago

@ccodecamp Ideally cypress should not block any network request as you know under the hood it runs electron (headless chrome browser). Can you please double check your cypress config. I would say if you can re-install cypress and do it fresh. Again it's upto you.

sbbird commented 4 years ago

+1 for not able to capture img request. Our site uses javascript to create a new image for sending a tracking request. Note that the javascript is served from CDN.

geyuqiu commented 3 years ago

thanks @suvendupanja I needed cy.wait(500); additionally to make it work

bahmutov commented 3 years ago

You can spy / intercept any requests using the new cy.intercept command. Find our examples in Stubbing using cy.intercept recipe

You can also spy on image resources directly using window.performance.getEntries() browser API, see Waiting for static resource recipe.

RichieRunner commented 3 years ago

hi @bahmutov , I've been trying cy.route2/cy.intercept since it came out, but unfortunately, it still cannot intercept the issue that I mentioned above:

The product I'm using (Adobe) isn't GTM, but it's the same concept. There's a script tag on my web page that loads in the javascript resource, which then exposes a new function onto the global window object. In my code, I am executing this function which then sends out a network request of type img/gif

This .gif request in the network tab does not get picked up by cy.intercept

image

jennifer-shehane commented 3 years ago

@RichieRunner If you can provide a failing example, please open an issue using cy.intercept() as this should work.

Lei-Xu commented 3 years ago

Hi @bahmutov.

I want to validate all the adobe analytics tag using cypress. below is part of my code:

cy.intercept('POST', 'https://XXXX', {statusCode: 200}).as('adobe-analytics-events') cy.wait('@adobe-analytics-events')

However, it seems that all the adobe analytics outgoing requests are "not caught" in cypress test runner console.

Screen Shot 2021-01-11 at 1 45 53 PM Screen Shot 2021-01-11 at 1 46 45 PM

My question is:

  1. Is it the cypress issue? having problems when dealing with adobe analytics.
  2. If not. could you point out my mistakes of implementation?
DharaniY commented 3 years ago

In the network tab you can the request. You can filter thru adobe filter b/ss. if you wan to access programatically you can use the following code

cy.visit("Pagename")
cy.window().then((win) => {
                var networkrequests = win.performance.getEntries().map(r => r.name);
               //previous step will give you array of all the Network request. 
              // You can filter the network request based on the you filter criteria (like Adobe b/ss string 
                  should be thet for GA : google-analytics etc)

})

Withing window you can filter the which request is adobe by name. You can put assertion on top it.

Hi ,can you please share sample code here, Thanks in advance

JayKishoreDuvvuri commented 2 years ago

Hi, can anyone help me with the sample code of yours for adobe tracking with cypress please? I have my network tab showing dynamic request names changing for every new login.

My case is similar to @ Lei-Xu mentioned above .

Can anyone share me sample code please?

Thanks in advance.

cheers, Jay.

HappyMan0001 commented 1 year ago

Yes, I am having the same issue. I can't intercept "/b/ss", I tried various ways for Cypress to intercept it. It works perfectly well for Google Analytics, but for Adobe, it does not "Timed out retrying after 5000ms: cy.wait() timed out waiting 5000ms for the 1st request to the route: adobe-analytics. No request ever occurred". Like JayKishoreDuvvuri mentioned: Can anyone share sample code? What I am trying to figure out, is what are you intercepting? how do you call it? Can I intercept Adobe Analytics? Can Cypress handle this? Any help is appreciated. Thanks

JayKishoreDuvvuri commented 1 year ago

Hi @HappyMan0001

thanks for your reply and pointing this out.

You can go through this, if you are interested: https://lnkd.in/dHWMcWMn - cypress https://lnkd.in/d_4HaErt - playwright

thank you!

HappyMan0001 commented 1 year ago

@JayKishoreDuvvuri, Hi thanks for sharing. My issue is that the cy.intercept() is not intercepting the API call. Cypress, just skips over it or doesn't find it. I keep getting stuck on that part or a response: Timed out retrying after 5000ms: cy.wait() timed out waiting 5000ms for the 1st request to the route: adobe-analytics. No request ever occurred. I'm curious has there been a fix for this after Cypress version 11.1? Because I'm using Cypress version 11.1.