Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Explicit wait doesn't work with regular expression and glob #567

Closed
behlrattan opened this issue Jul 20, 2017 · 18 comments
Closed

Explicit wait doesn't work with regular expression and glob #567

behlrattan opened this issue Jul 20, 2017 · 18 comments

Comments

@behlrattan
Copy link

  • Operating System:OSX
  • Cypress Version:19.4
  • Browser Version:Chrome 58.0.3029.110

Is this a Feature or Bug?

Bug

Current behavior:

CypressError: Timed out retrying: cy.wait() timed out waiting 5000ms for the 1st request to the route: 'submit'. No request ever occured.

Desired behavior:

Explict wait should work

How to reproduce:

Test code:

The endpoint on which I want to apply explicit wait is
api/v1/account/a5f35b5f-bc8f-4c7b-a79d-68950dc2fcb7/submit
api/v1/account/<unique application id for every request>/submit

cy.server()

//Tried Regex and Glob one at a time and not all together
cy.route(//api/v1/account/./submit/).as('submit')
cy.route('/api/v1/account/**').as('submit')
cy.route('/api/v1/account/
/submit').as('submit')
cy.get('button').click()
cy.wait('@submit').its('url').should('verify/complete')

Additional Info (images, stack traces, etc)

@jennifer-shehane
Copy link
Member

Hi @behlrattan, it's helpful when using globs to test your Globs in globtester or Regex in a regex checker like regex101. I was able to get the endpoint you specified to work with /api/v1/account/**/submit. Could you double check to see that this works in your example?

My globtester example

Also, I notice you are not defining a chainer in your final assertion:

cy.wait('@submit').its('url').should('verify/complete')  // incorrect

You need to define a chainer. You'll notice that the assertion will usually sound like a sentence "its url should include 'verify/complete'" like so:

cy.wait('@submit').its('url').should('include', 'verify/complete')  // correct 

@jennifer-shehane jennifer-shehane added the stage: needs information Not enough info to reproduce the issue label Jul 20, 2017
@behlrattan
Copy link
Author

Thanks @jennifer-shehane for the quick response. But, i'm afraid i'm still having issues (Timeout after 5 seconds on requestResponse.
On -- cy.wait('@submit').its('url').should('verify/complete') // incorrect
I agree, it was a typo from me.

As per the documentation https://docs.cypress.io/api/commands/wait.html#Timeouts

The first period waits for a matching request to leave the browser. This duration is configured by requestTimeout - which has a default of 5000 ms.

This means that when you begin waiting for an aliased XHR, Cypress will wait up to 5 seconds for a matching XHR to be created. If no matching XHR is found, you will get an error message that looks like: CypressError: Timed out retrying: cy.wait() timed out waiting 5000ms for the 1st request to the route: 'submit'. No request ever occured.

And that made me believe the request that i'm trying to build using glob is not working.
Please do note other place in my script i have successfully managed to use the explicit wait but without glob. I know the globtester example that you shared looks fine so at this moment i'am not sure what's wrong.

@brian-mann
Copy link
Member

Take a screenshot of your command log.

Cypress will indicate when an XHR matches an alias. You can also click on the XHR request and get more details.

Post that command log and a screenshot of the console output after clicking on the XHR.

@behlrattan
Copy link
Author

This is piece of code:
`cy.route('/api/v1/invest/**').as('submit')

cy.route('/api/v1/identity/**').as('identity')

cy.get('Button').click()

cy.wait(['@submit','@identity'])`

command log

xhr request endpoint

screen shot 2017-07-23 at 11 10 05 pm

@brian-mann
Copy link
Member

If your application is making a POST, that's why it's not working.

You need to tell cy.route you expect a POST because the default it stubs is a GET.

cy.route("POST", "api/v1/identity/**").as("identity")

@behlrattan
Copy link
Author

Thanks!, couple of things

  • POST worked for submit endpoint-
cy.route('POST', '/api/v1/invest/*/submit').as('submit')
cy.get('Button').click()
cy.wait('@submit')
  • But, POST call for identity endpoint doesn't work. After successful "submit" an immediate POST request is made to the identity endpoint. Following doesn't work
cy.route('POST', '/api/v1/invest/*/submit').as('submit')
cy.get('Button').click()
cy.wait('@submit')
cy.route('POST', '/api/v1/identity/*').as('identity')
cy.wait('@identity')

OR

cy.route('POST', '/api/v1/invest/*/submit').as('submit')
cy.route('POST', '/api/v1/identity/*').as('identity')
cy.get('Button').click()
cy.wait(['@submit','@identity'])

screen shot 2017-07-24 at 12 13 39 pm
screen shot 2017-07-24 at 12 21 31 pm

@brian-mann
Copy link
Member

brian-mann commented Jul 24, 2017

The XHR you are highlighting in the dev tools is not the one that matches what Cypress logged.

I am 100% confident there is not a bug with Cypress's stubbing behavior - all I think the problem is that you're not correctly writing your cy.route to match the URL that your request is making. If you did, Cypress would match it up.

You should use http://www.globtester.com/ to help you write a correct glob pattern.

@brian-mann
Copy link
Member

I'm going to close this issue as I don't believe there is anything wrong on our end. If you believe something needs to be changed please create a reproducible repo with the incorrect behavior.

@behlrattan
Copy link
Author

behlrattan commented Jul 24, 2017

The screenshot of XHR in the dev tools does match with what Cypress has logged. Its api/v1/identity/application id

@julian69
Copy link

julian69 commented Nov 3, 2017

Hi @behlrattan.
I came across this issue while trying to find a solution for a similar situation...
At first I thought it was something related to the URL, but I've tried lot of options and I always get the same response (Timed out retrying: cy.wait() timed out ...).
have you managed to work this out?
If so, may you please let me know what the right approach would be?
This is my piece of code:

        cy.server();
        cy.fixture("myData.json").then( myData => {

            const myDataArray = [ myData ];

            cy.route("GET", "/alerts**", myDataArray)
                .as("getDataArray");
        });

        cy.visit("/");

        cy.wait("@getDataArray").its("responseBody")
          .should("have.property", "type");

Thanks in advance.

@brian-mann
Copy link
Member

I'm assuming its timing out because your assertion is failing. Your assertion is failing because you're wrapping your myData object in an array and an array does not have a type property.

The assertion is failing because it should be failing :-P

@julian69
Copy link

julian69 commented Nov 3, 2017

Hi Brian.
Thanks a lot!

While you are right and I had to modify what you pointed out, I couldn't make the test work yet...
I'm using Cypress.minimatch to make sure my url matches. But when I pass it to route() I'm still getting the same error as before.

Cypress.minimatch("http://localhost:5000/v1/alerts", "**/alerts*", { matchBase: true });

Just for the sake of seeing what happen I tried "*" as my url and that way cy.wait() passes and I can see in the network info?t=1509676709990 containing the expected response, but the data doesn't appear to be available in my application.

Honestly, I'm a little bit at lost, so any suggestion is appreciated.
Thanks again.

@cosmocracy
Copy link

@brian-mann Just a side-mention that the failure to match POST should probably be included in the intro-level documentation as a note/gotcha. As a Cypress newbie I got bitten by the same problem--my XHR was using POST--and only after stumbling upon this GitHub issue did I learn the default was GET. (Better, perhaps, would be that if you don't specify, it would match either). Thank you

@jennifer-shehane
Copy link
Member

@cosmocracy I opened an issue in our docs for your suggestion here cypress-io/cypress-documentation#217. Our docs are open source, so feel free to contribute. :)

@jennifer-shehane
Copy link
Member

@julian69 I suggest playing around with Globtester if you are trying to match globs using minimatch.

I was unable to get a match with the url and glob you posted, but the glob **/alerts does however match http://localhost:5000/v1/alerts.

@jennifer-shehane jennifer-shehane removed the stage: needs information Not enough info to reproduce the issue label Nov 3, 2017
@julian69
Copy link

julian69 commented Nov 4, 2017

Thanks @jennifer-shehane for your answer.

I've been playing around with Cypress for a few days now and I apologise beforehand if what I'm asking is not relevant for this issue.

I though at first that the error I was getting was due the URL, but I tried again with a couple of matching options and still the same. Roughly, what I'm trying to do is to mock the data I'm consuming in my components using fetch. I'm working on a test environment and, otherwise, I should load data to the db every time in order to be able to run the test. As to make sure there was nothing wrong with my environment, I downloaded the "cypress-tutorial-build-todo-starter" and created a similar but simpler scenario but got stuck in the same place (Timed out retrying: cy.wait() timed out ...).
Am I missing something?

This is kind of how I get the data (not my real service, but same idea):

fetch('https://jsonplaceholder.typicode.com/posts/1')
        .then((resp) => resp.json()) 
        .then(function(data) {
            console.log(data)
 });

and this is how I'm trying to mock it:

it('mocking fetch response', () => {
        // const match = Cypress.minimatch("https://jsonplaceholder.typicode.com/posts/1", "**/posts/*", { matchBase: true });
        // match returns true
        cy.server();
        cy.route("GET", "**/posts/*", "fixture:example.json").as("getExample");
        cy.wait("@getExample").its("responseBody")
            .should("have.property", "name");
        cy.visit('/');
});

Thanks heaps!

@brian-mann
Copy link
Member

window.fetch is not supported yet.

Here's the open issue including a simple workaround: #95 (comment)

It will be supported once #687 has landed.

@julian69
Copy link

julian69 commented Nov 6, 2017

Thanks again for your time.
This last comment solved my problem.
Looking forward to the fetch support implementation.
Btw, congratulations, Cypress is awesome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants