cypress-io / cypress

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

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

Closed TheWanderingWalnut closed 3 years ago

TheWanderingWalnut commented 4 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

kuceb commented 4 years ago

@TheWanderingWalnut Thanks for the report. are you using any frameworks? any component libraries? any custom javascript listening to keyboard events? sometimes there are edge cases we miss. In vanilla javascript, we have tests around this scenario and they passed.

jennifer-shehane commented 4 years ago

Unfortunately we have to close this issue as there is not enough information to reproduce the problem. This does not mean that your issue is not happening - it just means that we do not have a path to move forward.

Please comment in this issue with a reproducible example and we will reopen the issue. 🙏

TheWanderingWalnut commented 4 years ago

@jennifer-shehane , I am unsure what you're looking for. Simply use cy.type() on an input field with a string with mixed case and it will reproduce the problem. This happens on various login screens around our app which I cannot share as they are proprietary. Please let me know what you're expecting for this bug to be investigated

jennifer-shehane commented 4 years ago

Simply use cy.type() on an input field with a string with mixed case and it will reproduce the problem

Recreating what you said does not reproduce the problem. There are likely other variables involved with the input or your test that we cannot isolate without you providing a completely reproducible example.

Index.html

<!doctype html>
<html lang="en">
<body>
  <input id="my-input">
</body>
</html>

Spec.js

it('works', () => {
  cy.visit("index.html")
  cy.get('#my-input').type('cAmElCaSe')
    .should('have.value', 'cAmElCaSe')
})
Screen Shot 2019-10-28 at 3 09 46 PM

Please provide a fully reproducible example so that we can fix your issue as quickly as possible. Thanks!

TheWanderingWalnut commented 4 years ago

@bkucera , Sorry, I missed your comment on my first glance. I do not believe we have anything particular on any of those fields, though I have setup a quick example repo with help from our devs and found that using the fields on that page it's fine, so I presume it's something we're doing on that page.

I'll work on this again likely this afternoon, but will have to take some time to work on other issues in the meanwhile. I'll update this issue with anything further I find.

TheWanderingWalnut commented 4 years ago

@jennifer-shehane Thank you for confirming you actually tested this. Had you confirmed you tested this in your first comment I wouldn't have worried about it. I've seen in the past when reporting bugs it's common to simply reject them, which I presumed from your previous comment's wording was what you'd done.

kuceb commented 4 years ago

@TheWanderingWalnut as a workaround, you may want to just set the values with cy.get(...).invoke('val', 'email@example.com'). If you can get us a reproducible I'll be happy to look more into this. Thanks!

TheWanderingWalnut commented 4 years ago

@Bkucera @jennifer-shehane I have not been able to reproduce this outside our app, though I can provide you below a public-facing internal test site which you can run a test against to see the bug.

The URL to use is https://cypressprodtesting.checkfront.com/ with the below code run against the provided page will fail in Cypress 3.5.0, while it will succeed in Cypress 3.4.1:

cy.get('#cf_id').click().type(partnerAccountActive);
cy.get('#cf_pw').click().type(partnerAccountActive);
cy.get('#cf_id').should('have.value', 'partnerAccountActive');
cy.get('#cf_pw').should('have.value', 'partnerAccountActive');

@Bkucera Thank you for the workaround, this is working for the time being, although there are other bugs in 3.5.0 which we need fixed before we can fully upgrade.

jennifer-shehane commented 4 years ago

@TheWanderingWalnut I was not able to reproduce any failure in the provided test case in 3.4.1 or 3.5.0.

I did replace partnerAccountActive with a string 'partnerAccountActive' and added a visit. This is passing for me in both versions.

it('types in both fields', () => {
  cy.visit('https://cypressprodtesting.checkfront.com/')
  cy.get('#cf_id').click().type('partnerAccountActive')
  cy.get('#cf_pw').click().type('partnerAccountActive')
  cy.get('#cf_id').should('have.value', 'partnerAccountActive')
  cy.get('#cf_pw').should('have.value', 'partnerAccountActive')
})
Screen Shot 2019-10-31 at 1 42 44 PM

Maybe there is some other variable I am missing. I tried in Canary 80, Chrome 78, Chromium 74 and Electron 73 on my osMac Mohave machine using `cypress open.

Please also try updating to our recently released 3.6.0, since it fixed some type bugs that were introduced in 3.5.

TheWanderingWalnut commented 4 years ago

@jennifer-shehane Hmmm, okay, it's still failing for me on 3.5.0 and 3.6.0 (sidenote, when did this come out? It isn't even in Cypress' changelog?). The only thing I can think of that might be different is in our app we have the Cypress BaseURL set to cypressprodtesting.checkfront.com, and then have a cy.visit('/'); at the top of our spec, then call the above code.

Sometimes I do have to run it a couple times, and other string which fail quite commonly include 'kevin@checkfront.com' as the username with whatever as a password.

Sorry, my bad, those were intended to be strings, that matches how we're using the code locally.

TheWanderingWalnut commented 4 years ago

@jennifer-shehane @Bkucera Could one or both of you please try reproducing this with the below repo? I made a repo with just Cypress in it with a simple test which is failing probably 40-60% of the time I run it. Please run this test at least ten times to ensure it will fail once.

https://github.com/TheWanderingWalnut/cypressRunningAgainstProductionCF

Note that in this test the login will ALWAYS FAIL. This is just to demonstrate how Cypress v3.5.0+ will fail to type into the fields correctly. It appears to be rushing through and typing the last part of the username into the password field, which is causing test failures in CI for us.

Thank you!

oak-wildwood commented 4 years ago

I can confirm this reproduces the issue. It seems to take a few tries but for me, after 3-5 successful attempts it only types the first 2 or 3 letters. It seems to fail a lot more after that happens. Hitting Stop from the TR and rerunning it almost always succeeds the first couple of runs.

I was able to comment out everything reducing to just:

cy.get('#cf_id').type('partnerActive')

And still reproduce it. @jennifer-shehane can we reopen this?

jennifer-shehane commented 4 years ago

Have confirmed, this fails occasionally, especially after rerun in 3.6.0 in both Chrome and Electron.

This is irrespective of any characters being capitalized.

it("Logs in as a partner", () => {
  cy.visit("http://cypressprodtesting.checkfront.com")
  cy.get('#cf_id').type('partner')
    .should('have.value', 'partner')
})

3.4.1

Passes on multiple reruns

Screen Shot 2019-11-06 at 12 05 04 PM

3.5.0

Fails when rerunning the spec file. Also fails in 3.6.0

Screen Shot 2019-11-04 at 2 17 33 PM

Events table indicates that it typed the full word 'partner', even though it only typed 'pa' into the email input and seemed to type the rest into the password field.

Screen Shot 2019-11-04 at 2 15 41 PM
YOU54F commented 4 years ago

I'm running 3.4.1 with the following deps, and see this occuring intermittently on multiple fields, often missing the @ in emails, or dropping a digit off in a phone number field (we see it mostly in chrome, but also in electron too)

   "@cypress/browserify-preprocessor": "^2.1.1",
    "@slack/client": "^5.0.2",
    "@types/cypress-axe": "^0.4.0",
    "@types/node": "^12.7.8",
    "aws-sdk": "^2.511.0",
    "axe-core": "^3.3.1",
    "browserify": "^16.5.0",
    "cypress": "3.4.1",
    "cypress-axe": "^0.5.1",
    "cypress-failed-log": "^2.5.1",
    "cypress-multi-reporters": "^1.2.1",
    "cypress-slack-reporter": "^0.5.0",
    "husky": "^3.0.3",
    "lint-staged": "^9.2.1",
    "mocha": "^6.2.0",
    "mocha-junit-reporter": "^1.23.1",
    "mochawesome": "^4.1.0",
    "mochawesome-merge": "^2.0.1",
    "mochawesome-report-generator": "^4.0.1",
    "moment": "^2.24.0",
    "prettier": "^1.18.2",
    "shelljs": "^0.8.3",
    "sonarqube-scanner": "^2.5.0",
    "tsify": "^4.0.1",
    "tslint": "^5.18.0",
    "tslint-config-prettier": "^1.18.0",
    "tslint-no-focused-test": "^0.5.0",
    "typescript": "^3.5.3",
    "uuid": "^3.3.2",
    "xlsx": "^0.15.1"

Code for the fields as follows, everything written in typescript and uses browserify preprocessor

  public populateContactDetails({
    emailAddress,
    phoneNumber
  }: ContactDetailsOverridableFields = {}) {
    cy.get(dataTestId("contactDetails_emailAddress"))
      .should("be.visible")
      .type(emailAddress || "test@test.com");
    cy.get(dataTestId("contactDetails_phoneNumber"))
      .should("be.visible")
      .type(phoneNumber || "0700000000");
  }

When it does error, I can see that cypress has attempted to type the full string, but the value appears to be missing one of the characters typed in

Screenshot 2019-11-11 at 16 13 39
kuceb commented 4 years ago

@YOU54F can you check the events table that gets logged in the console if you click on the .type command, and post a screenshot of it here? I have seen cases where the input/textarea gets blurred during the type, and that should be represented by the table.

Akshaya2312 commented 4 years ago

@jennifer-shehane when we could expect to get it to fix?

jennifer-shehane commented 4 years ago

@Akshaya2312 We are no longer able to reproduce this behavior in our latest release since the example site that was provided to test against has changed.

Unfortunately we'll have to close this issue if no reproducible example is provided. Can anyone provide a way to reproduce this in 3.8.0?

TheWanderingWalnut commented 4 years ago

Hello @jennifer-shehane,

Thank you for updating this ticket, although I wish you had informed me of the problems you had run into, rather than others who comment without examples. I have updated the example I provided, please look into this as soon as possible. If you run into any further problems, please let me know immediately so we can get this bug finally fixed.

Thank you, TheWanderingWalnut

jennifer-shehane commented 4 years ago

​I see that you have updated the repo to the changes made on the public facing application so that we can now run the tests - this is the piece that was missing. Thanks for providing this.

We close issues because, as you can see, issues pile up with no path forward. We are always open to reopen issues when a new reproducible example is produced, so don't be alarmed. This is just our process.

I ran the code below and it is not failing to type the correct values into the inputs for me in 3.5.0, 3.7.0, 3.8.0 in Chrome 79, Chrome 74, or Electron, nor failing for the 20 times I reran the code in each situation.

Can you please paste a video of what is failing to type for you? And also ensure you are using version 3.8.0 of Cypress. If we are given a failing example - we will reopen this issue.

it("Types correctly into fields", () => {
  cy.visit("http://cypressprodtesting.checkfront.com")
  cy.get("#email")
    .click()
    .type("partnerActive")
    .should("have.value", 'partnerActive')
  cy.get("#password")
    .click()
    .type("partnerActive")
    .should("have.value", 'partnerActive')
})

sharpboy2008 commented 4 years ago

I also have same problem. has this solved? I am using invoke instead

sharpboy2008 commented 4 years ago

i am using 3.8.0. still have same issue. i am using invoke instead. could you pls look into it?and see if it can be fixed.

jennifer-shehane commented 4 years ago

@sharpboy2008 Please provide a reproducible example - HTML & test code to run. We do not currently have an example to reproduce this bug, so this is not fixed / no work has been done on this issue and cannot fix until that is provided using 3.8.0.

sharpboy2008 commented 4 years ago

@jennifer-shehane Here is sample .not always can be produciable. but when trying many times ,it would appear.

      cy.visit('https://law.wkinfo.com.cn/')
      cy.contains('登录').click()

      cy.get('#login-username').type('XXTEXXY.xxlpnc').should("have.value", 'XXTEXXY.xxlpnc')
      cy.get('#login-password').type('wqswweewres88').should("have.value", 'wqswweewres88')
sharpboy2008 commented 4 years ago

username and password can be any.chrome version 79.0.3945.88

sharpboy2008 commented 4 years ago

image

sharpboy2008 commented 4 years ago

image

sharpboy2008 commented 4 years ago

sometimes, it always '';

mkickmaier commented 4 years ago

Having the same problem after upgrading from 3.3.0 to 3.8.1. Test was not changed. I have a failing rate of about 30%. Curently haven't more information. I'm still investigating.

pawelrudnicki commented 4 years ago

I have the same problem. When I try to enter a random sequence of numbers starting with zero, it only enters zero (first character). It works on 3.4.1 but on 3.8.0 it fails. Keyboard event object contains full text.

LoaderB0T commented 4 years ago

We are having the same issue when using cy.get('#some-input').clear().type('\\\\machinename.domain.local\\C:\\folder\subfolder'); Cypress stops typing after 'C:\'

Edit: Ok nevermind, we found out that this was caused by an exception in our code thrown in the background during typing.

DreamCreater commented 4 years ago

I am facing the same problem. The failing rate is around 40%.

Code:

cy.get('#currency').type('241 14001 45191');
cy.get('#currency').invoke('val').should('contain', 'DK 241 14001 45191');

I am seeing in the logs that, sometime the typed value is missing '0' (typed value: 241 1401 45191) and some time its missing '1' (typed value: 24 1401 45191) .

jennifer-shehane commented 4 years ago

@sharpboy2008 I can recreate your issue as described in 3.8.1 and it does look to be the same issue as the original one being opened.

I cannot recreate this issue in 3.7.0 actually - the test always passes. This makes me think this is slightly different in some way from the original issue.

Sometimes only a few characters are typed, sometimes no characters - it changes depending on reload of tests (ctrl+r).

Test code

it('types - char', () => {
  cy.visit('https://law.wkinfo.com.cn/')
  cy.contains('Login').click()
  cy.get('#login-username').type('XXTEXXY.xxlpnc').should("have.value", 'XXTEXXY.xxlpnc')
  cy.get('#login-password').type('wqswweewres88').should("have.value", 'wqswweewres88')
})

one test that only typed a few chars

Screen Shot 2020-01-08 at 5 25 34 PM

corresponding events table

Screen Shot 2020-01-08 at 5 24 35 PM

@sharpboy2008 I would suggest rolling back to Cypress 3.7.0 in the meantime for your issue.

pawelrudnicki commented 4 years ago

@jennifer-shehane What about my issue? Did you try recreate this scenario in 3.8.1?

VesterDe commented 4 years ago

I ran into this issue as well today. The strange thing is that I started using cypress a few days ago with 3.8.1, and it worked fine until today, when it suddenly started failing 100% of the time. it varies a bit how far it gets, for instance sometimes it gets to "person@ema", other times it gets to "person@email.c" etc...

I've now fixed it by reverting all the way back to 3.4.0, where the failure rate seems to be 0%.

We do use angularjs though, so the problem may be in there. Still strange that it worked for a few days perfectly.

Ali-AlHalass commented 4 years ago

Dear great community, i have had the same error, the problem is that Cypress is typing to fast in it. The default input typing speed is 10ms. I solved my problems since i added an option while typing in an input field. You have just to increase the delay of typing! Like ->

cy.get('.loginInput').type('TestUser', {delay:70} );

delays between 70 and 100 was the perfect range i tried it with 50 ms, but it failed onced. since i updated it to 70 ms, the test now have been run over 600 times! without error.

Sorry for my bad english, i'm not a native english speaker.

Best wishes from germany

coleman17 commented 4 years ago

I too am seeing this issue after upgrading from v3.4.1 -> v3.8.2. Using it as such:

cy.get(this.numberField).type(searchCriteria).type('{enter}');

The searchCriteria we pass in could be 123456 and typically it will type {enter} after 12345, but missing the 6.

We are testing an Angular 8 project with Cypress.

bnss commented 4 years ago

FWIW, this solves the issue for me in v.3.8.2:

cy.get('.loginInput').click(); // Add this line
cy.get('.loginInput').type('TestUser');
Minho-Lee commented 4 years ago

I had a similar issue with this where

cy.contains('label', 'exampleLabel').find('input').focus().type('some text here');

only resulted in typing out the first character s.

I was able to get around this issue by adding { force: true } option to type().

My current cypress version is 3.8.2.

yaakov123 commented 4 years ago

@Codex0607 This solved my issue perfectly, although the timing was a bit off. It seems to me that this issue happens when there is an eventListener attached to the input on key events. In my case, I was doing something quite intensive on each keypress so it seemed to miss some keystrokes. It could be, and I haven't tested this, that if a login form is validating input on key events it could potentially cause it to miss.

Ali-AlHalass commented 4 years ago

@Codex0607 This solved my issue perfectly, although the timing was a bit off. It seems to me that this issue happens when there is an eventListener attached to the input on key events. In my case, I was doing something quite intensive on each keypress so it seemed to miss some keystrokes. It could be, and I haven't tested this, that if a login form is validating input on key events it could potentially cause it to miss.

our company has a validation on input fields too, you can try to add after your type() an assertion like: type('test1'). should('have.value','test1'). or select your input field and do a callback on it within a then block and do the typing and the assertions in the then block.

yk1711 commented 4 years ago

I have similar issues in 3.8.0 and it also happens around ~30-50% of the time like some of the posts above reported.

When printing the keyboard events table shows that each character was triggered, but for me the input stays completely empty (not partially filled like some other reports here)

Another common theme for me is that all my forms that fail with this are inside a dialog which is positioned over a position:fixed container backdrop (similar to the popular Bootstrap Modal component, etc.)

If I have 5 inputs that are typed into one after the other, usually only the very first input remains unfilled, and the 2nd+ is filled properly.

The only solution/hack that works for me for now is doing cy.wait(1000) (lower delays also didn't seem to help) before I'm about to type into something.

lynchem commented 4 years ago

We just encountered this in 4.0.2 . Our's was a very simple

cy.get('[data-schema-key="amount"]')
  .clear()
  .type("5000");

It would only type 5 in 4.0.0 and in 4.0.2 sometimes gets 50 or 500. We have many other uses of type around our tests but only this one was failing.

I repeated the same command after it and second time it types the full 5000.

We added the {force: true} and it's fine now.

It happens running just this test in isolation, not sure how I could try reproduce it but if there's anything we can do to try help find the cause let me know.

saschahofmann commented 4 years ago

I was suspecting that maybe our implementation of the input was causing the issues (we are using a modified version of the html input in React) but I just verified that the cy.get('input').type('Something') sometimes just doesn't trigger the onKeyDown event.

Edit: I thought I had tried adding {force: true} but seems like I didn't because adding it now solved most of the issues. Is this a hint to what is going wrong? I tried to read about what it does but not sure how the inputs can be in an "actionability state" only sometimes.

raulyarooms commented 4 years ago

same issue here on 3.8.3 just updated from 3.4.1 - here is ok :)

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 regression. 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 this is no work has been done on this issue and cannot be fixed until that is provided.

saschahofmann commented 4 years ago

I just tried setting up an example using cypress 3.8.3 and react. So far all tests pass consistently. I will have another look later. If someone else wants to have a try, here is the repo feel free to commit.

hoscarcito commented 4 years ago

This is happening to me only on a textarea no matter what option I set (delay, force, etc)

jennifer-shehane commented 4 years ago

@hoscarcito Please can you provide HTML + test code to reproduce?

hoscarcito commented 4 years ago

After one day trying this, I've just found the error. Our app is written in React and eveytime we change the location it fires a setTimout to fire a redux action to clean alerts after x seconds. This leads to weirds re-renders in the middle of the tests that, even if they don't update the component at all, it prevents Cypress to keep typing. Also, we had other issues with elements being apparently unmounted. But again, this was all related to firing this redux action with the timer to clear notifications.

Thanks!

willgdjones commented 4 years ago

I can confirm that we are witnessing this behaviour too.