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

cy.type() cannot type text to CkEditor text area #26155

Closed
jeanabanto opened this issue Mar 20, 2023 · 7 comments
Closed

cy.type() cannot type text to CkEditor text area #26155

jeanabanto opened this issue Mar 20, 2023 · 7 comments

Comments

@jeanabanto
Copy link

Current behavior

On Zendesk update, cy.type() command fails to type text to a CKEditor text area.

type.mp4

Desired behavior

cy.type() should be able to type text to the text area, otherwise the test will not be able to create a ticket. Typing a text to the text area is required in order to create a new ticket.

Test code to reproduce

I have created a sample test code to replicate the issue on this repository:
https://github.com/jeanabanto/cypress-zendesk

The relevant test for this issue is https://github.com/jeanabanto/cypress-zendesk/blob/main/cypress/tests/ticket.spec.ts.

Cypress Version

12.8.1

Node version

16.15.0

Operating System

macOS 13.2.1 (22D68)

Debug Logs

No response

Other

Trying to type text to the text area produces an uncaught exception
Screenshot 2023-03-20 at 12 04 26 pm

Was advised on discord to turn off uncaught exceptions, but doing that did not solve the issue, i.e., unable to type anything to the text area.

@lmiller1990 lmiller1990 self-assigned this Mar 20, 2023
@lmiller1990
Copy link
Contributor

lmiller1990 commented Mar 20, 2023

I am able to reproduce this:

(uncaught exception) CKEditorError: Cannot read properties of null (reading 'root')
Read more: https://ckeditor.com/docs/ckeditor5/latest/support/error-codes.html#error-Cannot read properties of null (reading 'root')

This is an issue from the CKEditor internals, I have no idea why it's occurring. Either way, I found a few fixes. Firstly, I tracked down this issue: ckeditor/ckeditor5#12802 that has lots of useful information. You can take a look there for more discussion around this issue - it seems to be non Cypress specific, but also an issue in other runners, like Selenium, etc.

Here is one way to do it, using setData - looks like a method specifically for testing and automation:

it('does work', () => {
  cy.visit('https://ckeditor.com/ckeditor-5/demo/feature-rich/')
      cy.get('.ck-content').contains('Discover')
      cy.get('[data-cke-tooltip-text="Select all (⌘A)"]').click().type('{backspace}')
      cy.get('.ck-content[contenteditable=true]').then(el => {
        // @ts-ignore
        const editor = el[0].ckeditorInstance  // If you're using TS, this is ReturnType<typeof InlineEditor['create']>
        editor.setData('Typing some stuff')
    })
    cy.get('.ck-content').invoke('text').should('eql', 'Typing some stuff')
})

Alternatively, if you want to type character by character (no setData) you can do it with cypress-real-events:

it('does work', () => {
  cy.visit('https://ckeditor.com/ckeditor-5/demo/feature-rich/')
    cy.get('.ck-content').contains('Discover')
    cy.get('[data-cke-tooltip-text="Select all (⌘A)"]').click().realType('{backspace}')
    cy.get('.ck-content[contenteditable=true]').realType('Typing some stuff')

    cy.get('.ck-content').invoke('text').should('eql', 'Typing some stuff')
})

I updated your test to use the realType method - I'm not sure which is best for your use case, but I got the ticket.spec.ts to pass. Here's the diff: https://github.com/jeanabanto/cypress-zendesk/compare/main...lmiller1990:cypress-zendesk:issue-26155?expand=1

Hopefully this helps. Let me know if you need anything else.

@jeanabanto
Copy link
Author

jeanabanto commented Mar 20, 2023

Thanks @lmiller1990 for the quick response. The cypress-real-events looks good, but I read it only supports chromium browsers. Sometimes Cypress breaks in chromium browsers, and would work well in Firefox (experienced this with Salesforce). I tried out the setData and was able to set text to the CKEditor, so for now I'll go with that.

It would be most ideal if Cypress cy.type() can be updated to fix this issue in future releases (similar to how realType can type just fine). Having to implement workarounds here and there in Cypress makes for longer and sometimes more complicated looking test scripts.

@lmiller1990
Copy link
Contributor

It sure would be nice to make cy.type() handle cases in the same way as cy.realType(), I think there's some limitations (some browsers not supporting the full CDP, like Firefox etc). We will revisit more tight integration with realType() etc in a separate issue. I'm not sure we can change cy.type() for a specific library (eg CKEditor).

Seems like setData is the most reliable way to handle this for CKEditor for now. I hope this works for your current use case.

Sometimes Cypress breaks in chromium browsers

What kind of issues do you encounter? If it's related to RAM usage, you could try experimentalMemoryManagement, documented here: https://docs.cypress.io/guides/references/experiments

@anilpujaraofficial
Copy link

(uncaught exception)CKEditorError: Cannot read properties of null (reading 'root')
Read more: https://ckeditor.com/docs/ckeditor5/latest/support/error-codes.html#error-Cannot read properties of null (reading 'root')

how can solve this probleam

@NicoleDing0314
Copy link

I am able to reproduce this:

(uncaught exception) CKEditorError: Cannot read properties of null (reading 'root')
Read more: https://ckeditor.com/docs/ckeditor5/latest/support/error-codes.html#error-Cannot read properties of null (reading 'root')

This is an issue from the CKEditor internals, I have no idea why it's occurring. Either way, I found a few fixes. Firstly, I tracked down this issue: ckeditor/ckeditor5#12802 that has lots of useful information. You can take a look there for more discussion around this issue - it seems to be non Cypress specific, but also an issue in other runners, like Selenium, etc.

Here is one way to do it, using setData - looks like a method specifically for testing and automation:

it('does work', () => {
  cy.visit('https://ckeditor.com/ckeditor-5/demo/feature-rich/')
      cy.get('.ck-content').contains('Discover')
      cy.get('[data-cke-tooltip-text="Select all (⌘A)"]').click().type('{backspace}')
      cy.get('.ck-content[contenteditable=true]').then(el => {
        // @ts-ignore
        const editor = el[0].ckeditorInstance  // If you're using TS, this is ReturnType<typeof InlineEditor['create']>
        editor.setData('Typing some stuff')
    })
    cy.get('.ck-content').invoke('text').should('eql', 'Typing some stuff')
})

Alternatively, if you want to type character by character (no setData) you can do it with cypress-real-events:

it('does work', () => {
  cy.visit('https://ckeditor.com/ckeditor-5/demo/feature-rich/')
    cy.get('.ck-content').contains('Discover')
    cy.get('[data-cke-tooltip-text="Select all (⌘A)"]').click().realType('{backspace}')
    cy.get('.ck-content[contenteditable=true]').realType('Typing some stuff')

    cy.get('.ck-content').invoke('text').should('eql', 'Typing some stuff')
})

I updated your test to use the realType method - I'm not sure which is best for your use case, but I got the ticket.spec.ts to pass. Here's the diff: https://github.com/jeanabanto/cypress-zendesk/compare/main...lmiller1990:cypress-zendesk:issue-26155?expand=1

Hopefully this helps. Let me know if you need anything else.

works, thank you

@hasan-sh
Copy link

We have a similar thing where we needed to set some data for testing purposes, here's how we did it.

    cy.window().then(win => {
        const editor = win.ckEditor;
        cy.get('.ck-editor__editable')
          .should('be.visible')
          .should('not.be.disabled');

        const data = "<code>to</code>";
        editor.setData(data);
        expect(editor.getData()).equal(data);
      })
        

You just need to set the ckEditor on the window variable in your JS/TS.

@someshver-pri
Copy link

someshver-pri commented Jun 6, 2024

For Drupal 10 Ckeditor 5 we can use the below code

cy.window().then(win => {
  win.Drupal.CKEditor5Instances.forEach(editor => editor.setData('<p>Test</p>'))
})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants