cypress-io / cypress

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

Cypress Doesn't Finish Typing Strings Before Continuing to Next Field #5480

Closed TheWanderingWalnut closed 3 years ago

TheWanderingWalnut commented 5 years ago

Current behavior:

When typing a long string into an input field, such as an email address to login in our case, Cypress 3.5.0 appears to no longer type the entire string. It bails on typing the complete string after the period in the email and never completely types the string. For example, test@webdomainhere.com would be typed as test@webdomainhere. in our app, failing the login.

I have also seen similar things with usernames using mixed case, such as associateEnabled would be typed as associate, stopping before the capital letter in the string.

Due to this bug we have had to roll back to using Cypress 3.4.1, where this worked fine.

Example screenshot showing a failed login in Cypress 3.5.0 where the email should've had 'com' typed after the period:

Screen Shot 2019-10-25 at 3 00 45 PM

Desired behavior:

Entire string passed to a cy.type() function should be typed into the input field.

Steps to reproduce: (app code and test code)

Type a long string, such as a long email address into a form field and then move on to a password field with a .click() and see that the end of the first string isn't entered.

Versions

Cypress v3.5.0 (v3.4.1 works fine, we have had to roll back) Mac OSX 10.14.6 Electron 61 / Chrome 78

saschahofmann commented 4 years ago

We migrated to cypress 4 and typing seems to work more reliably. I still haven't managed to build a minimal example but discovered a case where cypress actually revealed a bug in the current setup. I have two instances of the same react component which update an external state onBlur. I ran:

cy.findByDisplayValue('[store_id]').type('{selectall}COUNT([store_id])')
cy.findByDisplayValue('[revenue]').type('{selectall}SUM([revenue])', forceOption)

The first line outputs this to the console: image and the second one: image The first one behaves as expected while the second input is not updated at all, since it's apparently typing on the wrong element. I figured that typing on the first second element actually triggered the onBlur on the first and changed it to manually trigger the onBlur (if anyone has a better idea than cy.findByDisplayValue('COUNT([store_id])').focus().blur() I'd be excited to hear it). And voila the second input types just as fine.

I tested this behaviour manually and indeed if you type in the first input you need two clicks to be able to type in the second. Why exactly that happens, I am not sure but thought I'd share.

dwenaus commented 4 years ago

my problem is similar but different, on first page load (it's a php site) cypress does not type the first few letters correctly, but does type in the final letters! adding a wait() helps. but ugh.

cshouts-tasc commented 4 years ago

We do not currently have an example to reproduce this bug, so this is no work has been done on this issue and cannot be fixed until that is provided.

What if this is caused by a race condition? It may not be possible to provide a reliable means of reproducing the bug.

willgdjones commented 4 years ago

The only way I've found to avoid this issue is to use 3.4.x.

shivasrini commented 4 years ago

Not sure if this will constitute an example. But we have a page which has a bunch of text inside a p tag. If you want to edit the content then click on a button opens a tiny mce modal. The modal has a text area that sits inside an iframe. I use js chance to generate a random paragraph which I then use cy.type() to fill in and then click ok to close the modal and then validate the p tag in the page for the updated text. I consistently got it to fail where only 3/4ths of the text got typed in even with adding the delay option

chengzh2008 commented 4 years ago

we faced the same issue with 4.1.0. several options has been tried like delay/force. It failed about 5-10 % of the time.

jennifer-shehane commented 4 years ago

Please provide a way to reproduce

Hey everyone, we know this issue is happening and we really, really do want to fix this. But as of yet no one has provided a completely reproducible example that we can currently run that fails in 3.4.1 and passes in 3.5.0.

Please provide a reproducible example - the entire HTML & test code that we can fully run on our system.

We do not currently have an example to reproduce this bug, so no work has been done on this issue and cannot be fixed until that is provided.

phuwin commented 4 years ago

We are using React with hooks, and we had the similar problem. It happened also in chrome.

const LoginForm = () => {
  const [email, setEmail] = useState('');
  const formRef = useRef(null);
  const [analyticsSent, setAnalyticsSent] = useState(false);
  useEffect(() => {
    const onFocus = () => {
    if (!analyticsSent)  { 
      sendAnalytics();
      setAnalyticsSent(true);
    }
    if (formRef.current) formRef.current.addEventListener('focus', onFocus);
    return () => {
      formRef.current.removeEventListener('input', onFocus);
    };
  }, [analyticsSent, formRef]););
  return (
  <form onSubmit={handleLogIn} ref={formRef}>
    <input value={email} onChange={(e) => setEmail(e.target.value) } />
   ...
  </form> )
  ...
}

So the problem is that the <form>'s input eventlistener callback somehow interferes with <input />'s onChange. By sending analytics and setting local state, onChange callback isn't called. I worked this around by instead of using input event on the <form>, I use focus event on the <input/>:

formRef.current.querySelector('input').addEventListener('focus', onFormFocus);

I'm actually having a custom hook for form analytics, thats why i add custom event listeners on the formRef instead of form's input.

kimmosaarinen commented 4 years ago

I am seeing this behaviour also (React hooks in use as in above, if that matters).

BUT! I think I've pinpointed the problem to be easily reproduced by simply (and quite oddly) clicking the Cypress UI, e.g. collapsing and expanding the test spec hierarchy on the auto-scrolling left pane. Fails both with Electron and Chrome (on MacOS). But once you leave the browser window untouched (or running tests in headless mode), the whole test suite passes...

So the clicks on Cypress part of the UI during testing steals the focus on the test browser. Maybe it's intended and unavoidable, but certainly wasn't obvious to me.

Cypress v4.5.0.

andrewjruss7 commented 4 years ago

Hola comunidad, a mi me está ocurriendo el mismo problema que no terminar escribir una cadena de texto en la versión 4.5. Me está ocurriendo en este mismo momento. Al parecer no hay una solución, pero al menos aquí dejaré el caso. Un saludo.

Captura de Pantalla 2020-05-07 a la(s) 7 19 20 p  m
Rose-Lutz commented 4 years ago

Hi @jennifer-shehane, I may have found a way to reproduce it.

Actually, the first time I launch my test, everything is always ok.

But as soon as I relaunch the test (either by ctrl+S in my editor, or directly from the icon in the Test Runner), it systematically fails : only a part of my string is typed.

For example, if my code is : cy.get('#keyword').type('something quite long to type') then :

Adding a delay worsens the typing bug, since the string is cut as soon as the first character is typed. Ex : cy.get('#keyword').type('something quite long to type', {delay: 300}) => only 's' is typed.

To the contrary, each time I relaunch my test from scratch (i.e. I close the Test Runner window and relaunch my test from my tests list), the typing is ok.

I hope this will help!

Let me know if you reproduce it too this way.

ofhope commented 4 years ago

Using the GUI from yarn cy:open I ran through my spec 10 times. I got 4 passes with 6 failures on an email input cy.get('input[name="email"]').type('developers@ethicaljobs.com.au'); which was typing an incomplete email and failing the validation. [pass, pass, fail, fail, fail, fail, fail, fail, pass, pass]

In the attachment you can see the command next to the resulting form input.

Screen Shot 2020-05-22 at 3 38 29 pm

Using the cypress-file-upload plugin and running testing in Chrome 81.

"cypress": "^4.5.0",
"cypress-file-upload": "^4.0.6",

I believe its a fairly vanilla install currently, this is the first test. I'll try and create a project from scratch to attempt to replicate.

I'm interacting with an iframe directly before the email input


    cy.get('iframe[width=304]')
      .then($iframe => {
        const $body = $iframe.contents().find('body');
        cy.wrap($body)
          .find('.recaptcha-checkbox-border')
          .should('be.visible')
          .click();
      });

    cy.get('input[name="email"]').type('developers@ethicaljobs.com.au');
    cy.get('input[name="firstName"]').type(name);
    cy.get('input[name="lastName"]').type('testLname');
    cy.get('input[name="phone"]').type('12344321');

The odd thing I find is cypress has proven to be reliable between async callbacks. Its such an odd thing for it to fail on.

rodrigosanchezg8 commented 4 years ago

I am experiencing this on 4.6.0. Can't provide example but in my case this won't happen at the very first time cypress types, for instance, my test first authenticates typing successfully but after navigating through the application and typing again it truncates the strings. What is solving the issue for me every time is to use clear method just as

cy.get('input[name="input.lastName"]').clear().type(lastName).should('have.value', lastName);
AnuragGalvanize commented 4 years ago

Hi Team, I am able to reproduce the above mentioned issue with 4.7.0. Here is the code snippet:

/// <reference types="Cypress" />
describe("visit the link", function () {
  it("visiting website", function () {
    cy.visit("www.amazon.com");
    cy.get("#twotabsearchtextbox").type("Mobile phone");
    cy.get(".nav-search-submit .nav-input").click();
  });
});

image

voyy commented 4 years ago

4.8.0 - bug is still there.

voyy commented 4 years ago

I am experiencing this on 4.6.0. Can't provide example but in my case this won't happen at the very first time cypress types, for instance, my test first authenticates typing successfully but after navigating through the application and typing again it truncates the strings. What is solving the issue for me every time is to use clear method just as

cy.get('input[name="input.lastName"]').clear().type(lastName).should('have.value', lastName);

Still flaky for me, but what did help was the delay parameter when putting input, something like:

cy.get(EMAIL_LOCATOR) .type(emailConst, { delay: 100 }) .should('have.value', emailConst);

abhinaba-ghosh commented 4 years ago

any update?

FilepCsaba commented 4 years ago

@rodrigosanchezg8 thanks, the .clear() solved it for me as well 100% in 4.9.0 where i was still encountering it.

But ended up using something like this based on @voyy 's feedback:

Cypress.Commands.overwrite("type", (originalFn, element, text, options) => {
  if(!options || !options.delay){
    options = {delay: 100}
  }
  return originalFn(element, text, options)
});
FilepCsaba commented 4 years ago

Also not sure if this is in any way a relevant or even valid info, but in our team we only have this issue on windows machines, on MacOs this never happens.

willgdjones commented 4 years ago

I've definitely experienced this on MacOSX

Sent via Superhuman ( https://sprh.mn/?vip=williamgdjones@gmail.com )

On Mon, Jun 29, 2020 at 14:49:59, FilepCsaba < notifications@github.com > wrote:

Also not sure if this is in any way a relevant or even valid info, but in our team we only have this issue on windows machines, on MacOs this never happens.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub ( https://github.com/cypress-io/cypress/issues/5480#issuecomment-651097697 ) , or unsubscribe ( https://github.com/notifications/unsubscribe-auth/AAND4KDIUQPXPX774VZQ6NDRZCEXPANCNFSM4JFJRB7Q ).

Akta3d commented 4 years ago

Updated to 4.9.0 and same problem

ghost commented 4 years ago

Also not sure if this is in any way a relevant or even valid info, but in our team we only have this issue on windows machines, on MacOs this never happens.

It is same for every OS. I have same issue with headless electron on ubuntu in docker.

jennifer-shehane commented 4 years ago

I'm able to reproduce this given the example below.

it('test', () => {
  cy.visit('www.amazon.com')
  cy.get('#twotabsearchtextbox')
    .type('Mobile phone')
    .should('have.value', 'Mobile phone')
})

This is happening because a 'toaster' pops up midway through typing (sometimes) on the site which takes focus away from the input during type. You can see where the type events are going for each keyboard event by clicking on the TYPE in the command log and opening the events table in your DevTools.

If your application calls focus away from the currently focused input during typing, this can cause this behavior.

Screen Shot 2020-07-02 at 3 19 15 PM
Adil-Iqbal commented 4 years ago

I've had this problem on our own app. Interestingly, I was able to solve it by using the same solution I had to Issue #7306. This leads me to guess that this problem is related to how Cypress deals with re-rendered text inputs. Though I could be wrong.

Here is a link to my comment in that issue: https://github.com/cypress-io/cypress/issues/7306#issuecomment-642917537

austin43 commented 4 years ago

@jennifer-shehane The bug happens for me without the input losing focus when using react ionic's "ion-textarea" in cypress@4.9.0. The text that ends up in the input is "Hy, how are you?" (missing the "e").

image

Adding a delay of 500ms before typing solves it, but I can't go this route in good conscience.

EDIT

I should mention adding a 500ms delay only solves it most of the time. It will still happen, making my tests undeterministic.

vrknetha commented 4 years ago

I could reproduce this issue in one of the text boxes

image

I have typed the input, assert for it and it fails.

image

Fyi, While typing, we fetch data from API.

gcostafinkel commented 4 years ago

I too have experienced this problem.

I have the cy.get('something').type() in around 15 different input fields on a test I do, and most of the times I run, around 13 or 14 are typed perfectly, but most of the time there is one or two that misses letters. And its completely random, both which field this happens and also how many letters it misses.

If I run, for example: cy.get('#AnyId1').type("TypingAnythingHere") cy.get('#AnyId2').type("TypingAnythingHere") cy.get('#AnyId3').type("TypingAnythingHere")

Sometimes it will run perfect, but sometimes one of the items will be typed incomplete, such as "TypingAnythi", or "Typ", and its completely random which one will this happen, or how many letters it will miss.

peterkemenyas commented 4 years ago

I am experiencing this on 4.6.0. Can't provide example but in my case this won't happen at the very first time cypress types, for instance, my test first authenticates typing successfully but after navigating through the application and typing again it truncates the strings. What is solving the issue for me every time is to use clear method just as

cy.get('input[name="input.lastName"]').clear().type(lastName).should('have.value', lastName);

This helped me as well!

derting commented 4 years ago

My version is 4.12.1, this bug still there.

But using clear() before type() can improve.

all9lives commented 4 years ago

Updated

I had this issue on 5.0.0 when filling out a form input in a modal on a CMS Website (no react, angular etc). It would only fill a few characters and it was super inconsistent how many it would fill before it moved on and failed the assertion.

As a workaround, I first click the field, type into it (which doesn't always work), so I then clear and then type again, I also add a 100ms delay. This workaround while not ideal has had consistent results with 100+ successful runs.


cy.get('input[name="input.lastName"]')
  .click()
  .type(lastName, { delay: 100 });

cy.get('input[name="input.lastName"]')
  .clear()
  .type(lastName, { delay: 100 })
  .should("have.value", lastName);

I hope this helps.

srilakshmishankar commented 4 years ago

Whenever I try to type this text similar to this: 'test multi choice tile-8561b7ee-2290-4588-97c3-7729ea854be9' --> 2 out 5 times it fails as it either does not type completely or some characters are missing.

peterkemenyas commented 4 years ago

Hello @srilakshmishankar

I tried a suggestion from previous comments and used clear() method and after the type() method worked just fine

srilakshmishankar commented 4 years ago

Hello @srilakshmishankar

I tried a suggestion from previous comments and used clear() method and after the type() method worked just fine

I tried with clear() too but it does not help. May be I need to add delay but it is too slow with delay.

peterkemenyas commented 4 years ago

Hello @srilakshmishankar I tried a suggestion from previous comments and used clear() method and after the type() method worked just fine

I tried with clear() too but it does not help. May be I need to add delay but it is too slow with delay.

Did you chain the clear() and type()?

srilakshmishankar commented 4 years ago

Hello @srilakshmishankar I tried a suggestion from previous comments and used clear() method and after the type() method worked just fine

I tried with clear() too but it does not help. May be I need to add delay but it is too slow with delay.

Did you chain the clear() and type()?

Yes

srilakshmishankar commented 4 years ago

I tried most of the solutions here and no use. Typing keeps failing and making our tests flaky. I spent a lot of time on this issue but not even able to manage with a workaround which works always.

bahmutov commented 4 years ago

Is there a reproducible example, a complete code repo we can run to see the problem?

Sent from my iPhone

On Aug 27, 2020, at 18:36, sri notifications@github.com wrote:

 I tried most of the solutions here and no use. Typing keeps failing and making our tests flaky. I spent a lot of time on this issue but not even able to manage with a workaround which works always.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or unsubscribe.

dacort commented 4 years ago

@bahmutov I haven't been able to build an isolated repro, but in Metabase we've seen it particularly with our SQL editor ( https://github.com/metabase/metabase/pull/12687/files ) where there's some auto-complete functionality as well as in one of our smoketests (see #7911).

I'll see if I can build a small repo with just those bits of code.

bahmutov commented 4 years ago

Yeah that would be ideal

Sent from my iPhone

On Aug 31, 2020, at 13:09, Damon P. Cortesi notifications@github.com wrote:

 @bahmutov I haven't been able to build an isolated repro, but in Metabase we've seen it particularly with our SQL editor ( https://github.com/metabase/metabase/pull/12687/files ) where there's some auto-complete functionality as well as in one of our smoketests (see #7911).

I'll see if I can build a small repo with just those bits of code.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

rabidsloth commented 4 years ago

We also just ran into this issue, and none of the workarounds above seemed to help. However, we did find a fairly gross workaround which involves chaining together multiple .click().type('x') commands to type one character at a time.

Unfortunately, I also can't share any details about the application which is running into this issue as it's an internal application.

AnkitaRao commented 4 years ago

I am facing the same issue Cypress doesnot even finish typing a 11 character string 'AUtoChocBOM' it stops after typing A. ANy visibility on the progress of this fix would be appreciated

stuarth-inova commented 4 years ago

Also having terrible issues w/ Cypress sometimes typing the entire string into some fields, but sometimes not typing the entire string, totally wreaking havoc. It is a Vue app.

bahmutov commented 4 years ago

Please provide a small reproduction we can run to see it

Sent from my iPhone

On Sep 9, 2020, at 14:59, Stuart Holme notifications@github.com wrote:

 Also having terrible issues w/ Cypress sometimes typing the entire string into some fields, but sometimes not typing the entire string, totally wreaking havoc. It is a Vue app.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

willgdjones commented 4 years ago

From the above stories, and from my own experience trying, it is clearly quite difficult to create such a reproducible example.

I do understand how this benefits you when you are trying to debug an issue.

Nonetheless, is there now not sufficient evidence to suggest that there is an underlying issue that is giving many people problems which therefore warrants further investigation from Cypress?

Sent via Superhuman iOS ( https://sprh.mn/?vip=williamgdjones@gmail.com )

On Wed, Sep 9 2020 at 8:24 pm, Gleb Bahmutov < notifications@github.com > wrote:

Please provide a small reproduction we can run to see it

Sent from my iPhone

On Sep 9, 2020, at 14:59, Stuart Holme notifications@github.com wrote:

 Also having terrible issues w/ Cypress sometimes typing the entire string into some fields, but sometimes not typing the entire string, totally wreaking havoc. It is a Vue app.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub ( https://github.com/cypress-io/cypress/issues/5480#issuecomment-689767214 ) , or unsubscribe ( https://github.com/notifications/unsubscribe-auth/AAND4KABHXGUO2BMC4O5MSLSE7I5JANCNFSM4JFJRB7Q ).

bahmutov commented 4 years ago

Unfortunately, there is not enough information for us to investigate it. Mostly we suspect these issues to be caused by race conditions, something we have been describing in our blog posts, all starting with "When Can ..." that you can read at https://www.cypress.io/blog/

[image: Screen Shot 2020-09-09 at 4.48.32 PM.png]

On Wed, Sep 9, 2020 at 4:39 PM William Jones notifications@github.com wrote:

From the above stories, and from my own experience trying, it is clearly quite difficult to create such a reproducible example.

I do understand how this benefits you when you are trying to debug an issue.

Nonetheless, is there now not sufficient evidence to suggest that there is an underlying issue that is giving many people problems which therefore warrants further investigation from Cypress?

Sent via Superhuman iOS ( https://sprh.mn/?vip=williamgdjones@gmail.com )

On Wed, Sep 9 2020 at 8:24 pm, Gleb Bahmutov < notifications@github.com > wrote:

Please provide a small reproduction we can run to see it

Sent from my iPhone

On Sep 9, 2020, at 14:59, Stuart Holme notifications@github.com wrote:

 Also having terrible issues w/ Cypress sometimes typing the entire string into some fields, but sometimes not typing the entire string, totally wreaking havoc. It is a Vue app.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub ( https://github.com/cypress-io/cypress/issues/5480#issuecomment-689767214 ) , or unsubscribe (

https://github.com/notifications/unsubscribe-auth/AAND4KABHXGUO2BMC4O5MSLSE7I5JANCNFSM4JFJRB7Q ).

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/cypress-io/cypress/issues/5480#issuecomment-689808991, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAQ4BJUJFDANHQM35ETCLJ3SE7RX5ANCNFSM4JFJRB7Q .

-- Dr. Gleb Bahmutov, PhD

Schedule video chat / phone call / meeting with me via https://calendly.com/bahmutov gleb.bahmutov@gmail.com @bahmutov https://twitter.com/@bahmutov https://glebbahmutov.com/ https://glebbahmutov.com/blog https://github.com/bahmutov

dacort commented 4 years ago

Certainly seems like some sort of race condition. I've been trying for a few days, but can't reliably reproduce this.

We just experienced it the other day in a test and you can see in the image below the text should be select {{snippet: foo}}, but it ends up being select {{snippet: f}}oo. But then we rerun the test and it's fine. In every scenario we've experienced this, a rerun of the test usually works.

image

I think you should be able to see the circleci runs since it was on a public branch if that's at all helpful

stuarth-inova commented 4 years ago

Yes, after further examination our problem seems like a race condition.

Vue is rendering the elements really fast, but in one case our DB call can be slow. BUT we started waiting on those routes - made it better, but still an issue.

Now as far as we can tell sometimes Cypress grabs the element and starts typing after the API call ends, but before Vue can render the data in the field. And if the field is empty, apparently Vue deletes what Cypress has typed so far.

In another case we have a button that appears to render before the js is bound to it- so the desired action does not occur when Cypress clicks it too quickly.

Is there any way for Cypress to peer into the inner workings of something like Vue and wait until all of this js has loaded/finished executing?

Stuart

On Wednesday, September 9, 2020, Damon P. Cortesi notifications@github.com wrote:

Certainly seems like some sort of race condition. I've been trying for a few days, but can't reliably reproduce this.

We just experienced it the other day in a test and you can see in the image below the text should be select {{snippet: foo}}, but it ends up being select {{snippet: f}}oo. But then we rerun the test and it's fine. In every scenario we've experienced this, a rerun of the test usually works.

[image: image] https://user-images.githubusercontent.com/1512/92657634-04603f00-f2aa-11ea-8645-23e711ec0925.png

I think you should be able to see the circleci runs https://app.circleci.com/pipelines/github/metabase/metabase?branch=pull%2F13213 since it was on a public branch if that's at all helpful

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/cypress-io/cypress/issues/5480#issuecomment-689839959, or unsubscribe https://github.com/notifications/unsubscribe-auth/AARORV4E3AAI47AIHC2SED3SE7Z4ZANCNFSM4JFJRB7Q .

dacort commented 4 years ago

@bahmutov Think I've finally got a solid repro for this!

Check out https://github.com/dacort/cypress_type_repro

It'll require you to run the Metabase Docker image, but the test takes care of setting it up and shows both a failing and successful type test case. There is a drop list that pops up that could be causing the issue?

Let me know how else I can help! /cc @nemanjaglumac as he helped put together the repro.

bahmutov commented 4 years ago

@dacort thank you - I can see the text disappearing, investigating in https://github.com/bahmutov/cypress_type_repro

bahmutov commented 4 years ago

Ok, @dacort so I suspect this is event listener logic that has a delay in the popup

// always works
cy.get(".Icon-add_data").click();
popover().within(() => {
  cy.wait(500)
  cy.get("[contenteditable='true']").type("1+1+1+1+1+1")
  cy.get('input.my1').click()
})
// sometimes works
cy.get(".Icon-add_data").click();
popover().within(() => {
  cy.wait(400)
  cy.get("[contenteditable='true']").type("1+1+1+1+1+1")
  cy.get('input.my1').click()
})

How is that popup implemented? Is it a widget we can look in isolation to see its code?