cypress-io / cypress

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

cy.route url as a function #2593

Closed gnapse closed 6 years ago

gnapse commented 6 years ago

Current behavior:

Currently cy.route supports the url specified as a string or a function.

Desired behavior:

I'd like to propose enabling a third option, where url can be also a function.

This would allow to make more complex matching against the url. The function would return true if the url matches the route, or false if it does not.

The need behind it is that there are certain types of url matching that are difficult to express with strings or even regular expressions. Especially when wanting to detect the presence or absence of certain query parameters.

For example, imagine a web page that performs a request to load employees data in a list, initially unfiltered. We want to match that a request to /employees. But then we want to type in a search box, and match a second request that should occur to /employees?filter[search]=search%20phrase.

So far so good. But now imagine the request has also additional query parameters in between that are irrelevant to the test at hand. In our case this is so because we're using jsonapi, and we're passing also params to include additional resources, and for pagination.

So the above two ideal and simple URLs become these:

Unfiltered: /employees?page[number]=1&page[size]=20&include=department Filtered: /employees?page[number]=1&page[size]=20&filter[search]=search%20phrase&include=department

We could work with regex, but it notice how almost any naive approach would make that the second url also matches the regex for the first one. So we need to use some sort of negative lookbehind approach on the url matching the first request, so that it does not match the second url. And negating regular expressions is difficult.

Hope I could make my case clear enough. Let me know if there's something I can clarify, or if this is easily achievable without facing the problems I am describing.

How would it look like

cy.route({
  url: url => url.indexOf('filter[search]=search%20phrase') >= 0
})

The above is a naive approach. But it would open the gate to actually parsing the URL's query parameters and do a very exact matching against what really matters.

jennifer-shehane commented 6 years ago

Thanks for the detailed request. There is a duplicate issue open here to accept function within route for url matching. https://github.com/cypress-io/cypress/issues/387