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

Cannot read property 'body' of null error when using .type() in a contenteditable body element inside an iframe #5930

Closed
jerryteps opened this issue Dec 11, 2019 · 13 comments · Fixed by #6571 · May be fixed by rangle/test-automation#29
Assignees
Labels
pkg/driver This is due to an issue in the packages/driver directory topic: cy.type ⌨️ type: regression A bug that didn't appear until a specific Cy version release v3.5.0 🐛 Issue present since 3.5.0

Comments

@jerryteps
Copy link

jerryteps commented Dec 11, 2019

Current behavior:

When trying to type inside of an iframe where the target element is either the body element with contenteditable=true or a child of the body, then an exception is throw from Cypress and the command fails. This worked successfully in 3.4.1, but is now failing in 3.7.0.

We use the Froala wysiwyg editor library v2.9 which creates the editor as an iframe with the body element set with contenteditable=true. So we can no longer run e2e tests which type text into the editor with Cypress 3.7.0.

Desired behavior:

Cypress successfully types into the specified element.

Steps to reproduce: (app code and test code)

An example of how to reproduce the error is by running the command,

cy.get('iframe').then(($iframe) => {
  const $body = $iframe.contents().find('body');
  cy.wrap($body).find('p').type('test');
});

With an iframe that contains,

<body contenteditable="true">
 ...
</body>

This produces the following exception.

TypeError: Cannot read property 'body' of null
    at getHostContenteditable (http://localhost:57715/__cypress/runner/cypress_runner.js:107362:29)
    at _getSelectionBoundsFromContentEditable (http://localhost:57715/__cypress/runner/cypress_runner.js:107280:29)
    at Module.getSelectionBounds (http://localhost:57715/__cypress/runner/cypress_runner.js:107602:14)
    at shouldUpdateValue (http://localhost:57715/__cypress/runner/cypress_runner.js:94737:81)
    at http://localhost:57715/__cypress/runner/cypress_runner.js:95442:14
    at Keyboard.performSimulatedDefault (http://localhost:57715/__cypress/runner/cypress_runner.js:95481:11)
    at Keyboard.simulatedKeydown (http://localhost:57715/__cypress/runner/cypress_runner.js:95388:25)
    at Keyboard.typeSimulatedKey (http://localhost:57715/__cypress/runner/cypress_runner.js:95411:12)
    at http://localhost:57715/__cypress/runner/cypress_runner.js:95159:17
From previous event:
    at http://localhost:57715/__cypress/runner/cypress_runner.js:95169:70
From previous event:
    at Keyboard.type (http://localhost:57715/__cypress/runner/cypress_runner.js:95168:62)
    at type (http://localhost:57715/__cypress/runner/cypress_runner.js:87991:23)
    at onReady (http://localhost:57715/__cypress/runner/cypress_runner.js:88133:20)
    at runAllChecks (http://localhost:57715/__cypress/runner/cypress_runner.js:85227:14)
    at retryActionability (http://localhost:57715/__cypress/runner/cypress_runner.js:85235:16)
    at http://localhost:57715/__cypress/runner/cypress_runner.js:85241:7
From previous event:
    at Object.verify (http://localhost:57715/__cypress/runner/cypress_runner.js:85178:21)
    at handleFocused (http://localhost:57715/__cypress/runner/cypress_runner.js:88124:29)
    at Context.type (http://localhost:57715/__cypress/runner/cypress_runner.js:88179:12)
    at Context.<anonymous> (http://localhost:57715/__cypress/runner/cypress_runner.js:100860:21)
    at http://localhost:57715/__cypress/runner/cypress_runner.js:100381:33
From previous event:
    at runCommand (http://localhost:57715/__cypress/runner/cypress_runner.js:100363:14)
    at next (http://localhost:57715/__cypress/runner/cypress_runner.js:100498:14)
    at http://localhost:57715/__cypress/runner/cypress_runner.js:100521:18
From previous event:
    at next (http://localhost:57715/__cypress/runner/cypress_runner.js:100498:34)
From previous event:
    at http://localhost:57715/__cypress/runner/cypress_runner.js:100535:37
From previous event:
    at run (http://localhost:57715/__cypress/runner/cypress_runner.js:100527:15)
    at Object.cy.(anonymous function) [as visit] (http://localhost:57715/__cypress/runner/cypress_runner.js:100894:11)
    at Context.runnable.fn (http://localhost:57715/__cypress/runner/cypress_runner.js:101081:20)
    at callFn (http://localhost:57715/__cypress/runner/cypress_runner.js:30931:21)
    at Test.../driver/node_modules/mocha/lib/runnable.js.Runnable.run (http://localhost:57715/__cypress/runner/cypress_runner.js:30924:7)
    at http://localhost:57715/__cypress/runner/cypress_runner.js:104009:28
From previous event:
    at Object.onRunnableRun (http://localhost:57715/__cypress/runner/cypress_runner.js:103998:17)
    at $Cypress.action (http://localhost:57715/__cypress/runner/cypress_runner.js:97629:30)
    at Test.Runnable.run (http://localhost:57715/__cypress/runner/cypress_runner.js:102935:20)
    at Runner.../driver/node_modules/mocha/lib/runner.js.Runner.runTest (http://localhost:57715/__cypress/runner/cypress_runner.js:31398:10)
    at http://localhost:57715/__cypress/runner/cypress_runner.js:31504:12
    at next (http://localhost:57715/__cypress/runner/cypress_runner.js:31318:14)
    at http://localhost:57715/__cypress/runner/cypress_runner.js:31328:7
    at next (http://localhost:57715/__cypress/runner/cypress_runner.js:31260:14)
    at http://localhost:57715/__cypress/runner/cypress_runner.js:31296:5
    at timeslice (http://localhost:57715/__cypress/runner/cypress_runner.js:26364:27)

Versions

Cypress 3.7.0, 3.6.0, 3.5.0

@jerryteps jerryteps changed the title Cypress throws an exception when trying to type in a contenteditable body element inside of an iframe Exception when trying to type in a contenteditable body element inside of an iframe Dec 11, 2019
@jerryteps jerryteps changed the title Exception when trying to type in a contenteditable body element inside of an iframe Exception when trying to type in a contenteditable body element inside an iframe Dec 11, 2019
@jennifer-shehane
Copy link
Member

I confirmed, this is a regression introduced in 3.5.0.

index.html

<!DOCTYPE html>
<html>
<body>
<iframe src="iframe.html" title="iframe Example 1"
  width="400" height="300"></iframe>
</body>
</html>

iframe.html

<!DOCTYPE html>
<html>
<body contenteditable="true">
  <p>foo bar</p>
</body>
</html>

spec.js

it('test', () => {
  cy.visit('index.html')
  cy.get('iframe').then(($iframe) => {
    const $body = $iframe.contents().find('body')
    cy.wrap($body).find('p').type('test')
  });
})

3.4.1

Screen Shot 2019-12-16 at 3 34 54 PM

3.5.0

Screen Shot 2019-12-16 at 3 36 39 PM

@jennifer-shehane jennifer-shehane added v3.5.0 🐛 Issue present since 3.5.0 type: regression A bug that didn't appear until a specific Cy version release pkg/driver This is due to an issue in the packages/driver directory topic: cy.type ⌨️ labels Dec 16, 2019
@cypress-bot cypress-bot bot added the stage: ready for work The issue is reproducible and in scope label Dec 16, 2019
@brian-learningpool
Copy link

Just a note that this affects CKEditor also, as it uses an iframe too.

@ghost
Copy link

ghost commented Jan 3, 2020

Following this thread as it's affecting all my cypress tests that have iframes in them.

@jennifer-shehane jennifer-shehane changed the title Exception when trying to type in a contenteditable body element inside an iframe Cannot read property 'body' of null error when using .type() in a contenteditable body element inside an iframe Jan 13, 2020
@BusseBu
Copy link

BusseBu commented Feb 3, 2020

Cannot update cypress version in my project because of that.

@Naninani
Copy link

Naninani commented Feb 5, 2020

@jennifer-shehane Any update? Please give us eta on the fix.

Due to this we are stuck with 3.4.1 and we cant use the latest 18.04 container because of #6212.

So its a circle of doom.

@ghost
Copy link

ghost commented Feb 8, 2020

Yes we are heavily affected by this and are stuck on a previous version. We really want to upgrade to 4.0 which has Firefox and Edge support.

@shivasrini
Copy link

Ditto with all the above comments

@ghost
Copy link

ghost commented Feb 20, 2020

Hmm I think it would be related to this commit :

9b1f589#diff-f7e9a0aa25f3d0c1f0845eeb68e3dac4

TypeError: Cannot read property 'body' of null at getHostContenteditable (http://localhost:57715/__cypress/runner/cypress_runner.js:107362:29)

The error comes from getHostContenteditable

before 3.5.0 the following function _getSelectionBoundsFromContentEditable had a safe guard to only call getHostContenteditable if we have a valid rangeCount

if (sel.rangeCount) {	
      //# get the first (usually only) range obj	
      const range = sel.getRangeAt(0)	
      const hostContenteditable = getHostContenteditable(range.commonAncestorContainer)
}

After 3.5.0

const _getSelectionBoundsFromContentEditable = function (el) {
    const doc = $document.getDocumentFromElement(el)
    const hostContenteditable = getHostContenteditable(range.commonAncestorContainer)	  
    const range = _getSelectionRange(doc)
    const hostContenteditable = getHostContenteditable(range.commonAncestorContainer)
      if (hostContenteditable === el) {
          .... 
        }
}

I added back validation to check first if we have a valid range count :

const _getSelectionBoundsFromContentEditable = function (el) {
  const doc = $document.getDocumentFromElement(el)

  const sel = doc.getSelection()

  if (sel && sel.rangeCount) {
    const range = _getSelectionRange(doc)
    const hostContenteditable = getHostContenteditable(range.commonAncestorContainer)

    if (hostContenteditable === el) {
      return {
        start: range.startOffset,
        end: range.endOffset,
      }
    }
  }

  return {
    start: 0,
    end: 0,
  }
}

The test is green but I don't see any text get typed into the iframe

@jennifer-shehane any insights into why this might be? Trying to wrap my head around this issue.

image

@kuceb
Copy link
Contributor

kuceb commented Feb 24, 2020

I'm working on a fix for this

@cypress-bot cypress-bot bot added stage: work in progress and removed stage: ready for work The issue is reproducible and in scope labels Feb 26, 2020
@kuceb
Copy link
Contributor

kuceb commented Feb 26, 2020

@Naninani that issue you link is closed as fixed. Can you open a new one if you're still having that problem?

@cypress-bot cypress-bot bot added stage: needs review The PR code is done & tested, needs review and removed stage: work in progress labels Feb 26, 2020
@cypress-bot cypress-bot bot added stage: pending release and removed stage: needs review The PR code is done & tested, needs review labels Feb 27, 2020
@cypress-bot
Copy link
Contributor

cypress-bot bot commented Feb 27, 2020

The code for this is done in cypress-io/cypress#6571, but has yet to be released.
We'll update this issue and reference the changelog when it's released.

@ghost
Copy link

ghost commented Feb 28, 2020

Hello, since the code for this is done but it's not yet released, why is the ticket closed? Also, what version of cypress would we need to install to include the fix for this once this is fixed?

@cypress-bot
Copy link
Contributor

cypress-bot bot commented Feb 28, 2020

Released in 4.1.0.

This comment thread has been locked. If you are still experiencing this issue after upgrading to
Cypress v4.1.0, please open a new issue.

@cypress-bot cypress-bot bot locked as resolved and limited conversation to collaborators Feb 28, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
pkg/driver This is due to an issue in the packages/driver directory topic: cy.type ⌨️ type: regression A bug that didn't appear until a specific Cy version release v3.5.0 🐛 Issue present since 3.5.0
Projects
None yet
7 participants