Hello!
Hope you are having a beautiful day!
Please do not make framework usability for developers more complex, because you have some vision, that is theoretically backed, but in practice makes life really hard.
Scenario:
Why it is so hard to have:
cy.get('input[field1]'.type('lala');
if (cy.hasElement('input[otp]')) {
cy.get('input[otp]'.type('lala');
}
This document contents is understandable, but I totally disagree - better to have support from you, than investigate how to hack around, so I do not need to rewrite back-end services for tests.
https://docs.cypress.io/guides/core-concepts/conditional-testing.html#The-problem
As a developer, I care only that my tests are quick to write and easy to read and debug. With Cypress this is not always the case, because a lot of things are counter-intuitive and require hackish solutions.
5 Biggest problem for our team in few months of usage:
I understand, that you could say: "this is feature and ...", but we have real people, who are trying their best, and different team members stumble up on same issues. So maybe you could help us and future clients? :)
We totally love Cypress and we hope these issues will be fixed in future releases.
Best regards!
EDIT: I have created and share my "hacks", how we needed to overcome Cypress limitations. Hopefully saves a week or two for the Cypress clients.
export default function(e, cb) {
cy.wait(1000);
cy.get('body').then(body => {
if (body.find(e).length > 0) {
cb();
}
});
}
import hasElement from './hasElement';
Cypress.Commands.add('hasElement', hasElement);
cy.hasElement('input[name=otpCode]', () => {
const otp = authenticator.generate(otpKey).toString();
modal.get('input[name=otpCode]').type(otp);
});
export default function(frameId, cb) {
cy.wait(5000);
cy.get(frameId).then($iframe => {
cy.wait(5000);
const $body = $iframe.contents().find('body');
cb({
contains: e => cy.wrap($body).contains(e),
get: e => cy.wrap($body).get(e),
});
});
}
import inFrame from './inFrame';
Cypress.Commands.add('inFrame', inFrame);
cy.inFrame('#gameIframe', frame => {
frame.contains('Some link or text').click();
frame.contains('Send').click();
});
For that you need to run local reverse proxy and run tests against it, example of our reverse proxy.
For that it would work on every developer computer, with subdomain and not changing /etc/hosts file, we created global DNS.
admin.localhost.io == 127.0.0.1
app.localhost.io == 127.0.0.1
var proxy = require('http-proxy-middleware');
var app = require('express')();
app.use(
'/',
proxy({
target: 'http://localhost:5000/',
ws: true,
changeOrigin: true,
router: {
'admin.localhost.io:5001':
'http://admin.real.external.address.com/',
},
}),
);
const port = 5001;
app.listen(port, () => console.log(`Reverse proxy app listening on port ${port}!`));
Hey @mxrguspxrt, thanks for the feedback. We hear you.
We try to keep our issues in our GitHub repo are reserved for a single bugs or feature request. Ideally, delivering one pull request to address the issue.
If you can, please let us know a single feature we can work to improve - with an example of current behavior and desired behavior as outlined in ourissue template.
To address the list of problems a little bit:
I assure you, we're working on resolving issues and read every new issue and comment in the repo. Thanks!
I fully support the idea of @mxrguspxrt, besides, I would be very grateful for the possibility to handle .get()
errors. I know that conditional testing described as wrong approach but for really complex scenarios which run on different platforms, this possibility will be very helpful. The described example works well for current statement checking:
Cypress.$('body').find(elementLocator).length > 0
But for condition waiting we should implement something like that:
let i = 0
for(i, i < 10, i ++){
if(Cypress.$('body').find(elementLocator).length > 0){
break;
}
cy.wait(1000)
}
but this is not the best way and not very flexible solution, because it doesn't work in all cases and we should combine it with recursion.
In my opinion, next will be more flexible:
try{
cy.get(elementLocator)
}catch(e){
// do something
}
We realy requires flexibility. Maybe this is not very right. But give us the opportunity to choose. Thank you.
@jennifer-shehane
Hi,
I need to have a condition in test, and (as far as I remember) similar example was found somewhere in the docs:
cy.get('some_btn).click()
cy.get('body').then(($body) => {
if ($body.find('.Table').length > 0) {
cy.log('ok')
} else {
cy.reload()
// some code next
}
})
but when running the test, I see in runner that it gets body
and then goes straight to cy.reload()
skipping waiting for .Table
.
what am I doing wrong?
When using jQuery's $body.find('.Table').length
, this evaluates once immediately when called. So by the time this code runs, the length is zero, there is no logic in your test on how to or how long to wait for this table to exist or not. This is exactly our reasoning for why conditional testing does not work on indeterminate DOM state like your example.
Hello Team,
Im trying the conditional test, where the selector is not present at initial, and clicking a button enables the selector.
So, when cy.get(elementLocator)
" CypressError: Timed out retrying: Expected to find element:" can we handle this, by conditioning it and executing click or some other action
Regards,
Ravi
what is the option to add time to wait for table? {timeout: N}
param in find()
is ignored in my case
My case is i am trying to click on a day on react calender to book tickets. Apart from past days, there are thousands of conditions on why a day can be disabled also for different events there are different conditions so its not possible currently for me to always determine which days will be disabled.
Further i am not trying to test if right days are disabled as its maintained by 3rd party. My test is ticketing flow
The solution:
use moments.js to get future day and click on it if its not disabled. If its disabled increment day by 1.
so need something like this
let btnBookDay = Cypress.moment().add(3,'days').date()
while(cy.get('time',{timeout:10000}).contains(btnBookDay).have('disabled'))
{
btnBookDay = btnBookDay +1
}
cy.get('time',{timeout:10000}).contains(btnBookDay).click()
however this doesn't have equivalent solution in cypress
Can’t you control the current date using cy.clock so you know what to expect
Sent from my iPhone
On Oct 12, 2019, at 09:14, Ayan Deb Barman notifications@github.com wrote:

My case is i am trying to click on a day on react calender to book tickets. Apart from past days, there are thousands of conditions on why a day can be disabled also for different events there are different conditions so its not possible currently for me to always determine which days will be disabled.
Further i am not trying to test if right days are disabled as its maintained by 3rd party. My test is ticketing flowThe solution:
use moments.js to get future day and click on it if its not disabled. If its disabled increment day by 1.so need something like this
let btnBookDay = Cypress.moment().add(3,'days').date()
while(cy.get('time',{timeout:10000}).contains(btnBookDay).have('disabled'))
{
btnBookDay = btnBookDay +1
}
cy.get('time',{timeout:10000}).contains(btnBookDay).click()however this doesn't have equivalent solution in cypress
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or unsubscribe.
Can’t you control the current date using cy.clock so you know what to expect
…
Sent from my iPhone
On Oct 12, 2019, at 09:14, Ayan Deb Barman @.*> wrote:  My case is i am trying to click on a day on react calender to book tickets. Apart from past days, there are thousands of conditions on why a day can be disabled also for different events there are different conditions so its not possible currently for me to always determine which days will be disabled. Further i am not trying to test if right days are disabled as its maintained by 3rd party. My test is ticketing flow The solution: use moments.js to get future day and click on it if its not disabled. If its disabled increment day by 1. so need something like this let btnBookDay = Cypress.moment().add(3,'days').date() while(cy.get('time',{timeout:10000}).contains(btnBookDay).have('disabled')) { btnBookDay = btnBookDay +1 } cy.get('time',{timeout:10000}).contains(btnBookDay).click() however this doesn't have equivalent solution in cypress — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or unsubscribe.
Its not about controlling the clock but i need to click on any future date to book tickets. But I don't have a concrete way to find available dates through api.
More detailed example is if i want to book tickets for Taj Mahal i need to click on future date to get the tickets list. However as its closed on Fridays and public holidays i need to account for it when click on the data. Similarly there are thousands of monuments which have thousands of criteria on which days should be disabled, including something just manual update by 3rd party due to operational issues. So its impossible for me to determine which day to click which is not disabled.
So i am using moments to determine near future date and need ability to check if the date is unavailable if yes need to increment the days
I was able to achieve my conditional testing by partially using cy.route() to gather available dates
also something like below.
cy.get('.react-calendar.shadow-sm.border.mx-auto.mb-3').siblings().each(($el) => {
if ($el.attr('class').includes('form-control shadow-sm mx-auto mb-4')) {
cy.get('.form-control.shadow-sm.mx-auto.mb4').children('option').first().next().invoke('val')
.then((val) => {
cy.get('.form-control.shadow-sm.mx-auto.mb-4').select(val)
})
}
if ($el.attr('class').includes('text-center pb-4')) {
cy.get('h5').contains('Select Time: ').children('div').click()
}
})
I also have a difficulty handling the conditional tests.For example I have a scenario where I need to click the radio buttons depending on visibility of element. The visibility depends on the account which I use. So I wanted to create a custom command 'click on the element depending on the visibilty'
if (x.isVisible)
click x
else if (y.isVisible)
click y
else if(z.isVisible)
click z
But when cypress doesn't find an element it will throw an exception , element cannot be found
While I was using selenium-java , I could handle it with try-catch block.So it would be good to let to check the visibility and return true/false and then perform action depending on it wihtout trowing exception
Hi, thanks for Cypress. Same request here, important for conditional testing apps based on its version or even based on changes that some views could have based on the current URL.
Hi, Its been great working on cypress. But i really like cypress to do conditional testing more easily.
Seems this is blocking me :(
Issue:
I have 4 elements
When clicked on each element a different module is showed so it seems there is no easy way to verify this?
Indeed. We generate links based on what comes from our CMS, we need to verify these links but Cypress does not allow this. Which means we have to switch framework or manually verify them.
please look at this feature or provide better documentation as you know testers also use this framework
if-else is easier to user
please look at this feature or provide better documentation as you know testers also use this framework
if-else is easier to user
I use this construction for conditionals, maybe it helps
cy.get('body').then((body) => {
if (body.find(selector).length > 0) {
Do something
} else {
Selector is not exist on current page
}
});
I have used this approach and its working fine
if (Cypress.$('body').find(`.c-button`).is(':visible')) cy.get(`.c-button`).click();
I actually think there must be a way to allow A-B scenarios -conditional testing -
I have a scenario that when I try to log in sometimes it's not allowed because the credantials block after a couple of login in a given hour.
So what I am tring to do is:
try to log in with this credentials if you can't try another pair.
why you're making it so hard to do a simple scenario like this!!!
After reading the doc & writing our e2e test cases in this library for a couple of days I'm quite disappointed at a few things. and this is one of them.
not being able to do a simple try
& catch
in a testing framework is laziness or just a consequence due to bad existing architecture.
I'm now looking at Puppeteer + Just as an alternative for cypress.
(Or maybe I was just naive of e2e..
Why is issue still active, you can already use the then() method and have your if statements on the retuned promise according to https://docs.cypress.io/api/commands/then.html#Syntax
You shouldn't be using try catch in tests anyways,
Most helpful comment
I fully support the idea of @mxrguspxrt, besides, I would be very grateful for the possibility to handle
.get()
errors. I know that conditional testing described as wrong approach but for really complex scenarios which run on different platforms, this possibility will be very helpful. The described example works well for current statement checking:But for condition waiting we should implement something like that:
but this is not the best way and not very flexible solution, because it doesn't work in all cases and we should combine it with recursion.
In my opinion, next will be more flexible:
We realy requires flexibility. Maybe this is not very right. But give us the opportunity to choose. Thank you.