javascripttypescriptcypressckeditorckeditor4.x

Using Cypress.IO to to setData on CKeditor 4


I'm using cypress to automate my project which uses CKeditor4.
I tried the following code to type in CKEditor because type method in cypress is very slow.

it('does work2', async() => {
  cy.visit('https://ckeditor.com/ckeditor-4/demo/')

  cy.get('#cke_1_contents iframe[title="Editor, ckdemoarticle"]')
    .then(async(el)=>{
      const body = await el.contents().find("body")[0];
      // @ts-ignore
      const editor = body.ckeditorInstance;
     editor.setData("<p>'Typing some stuff'</p>")
    });
})

But I can see below error on console

Unhandled rejection TypeError: Cannot read properties of undefined (reading 'setData')
at eval (https://ckeditor.com/__cypress/tests?p=cypress\e2e\test.cy.ts:75:36)
at step (https://ckeditor.com/__cypress/tests?p=cypress\e2e\test.cy.ts:43:23)
at Object.eval [as next] (https://ckeditor.com/__cypress/tests?p=cypress\e2e\test.cy.ts:24:53)
at fulfilled (https://ckeditor.com/__cypress/tests?p=cypress\e2e\test.cy.ts:15:58)From previous event:
at Promise.longStackTracesCaptureStackTrace [as _captureStackTrace] (https://ckeditor.com/__cypress/runner/cypress_runner.js:3486:19)
at Promise._then (https://ckeditor.com/__cypress/runner/cypress_runner.js:1239:17)

I realized ckeditorInstance is not available in CKEditor4.

I tried everything available in the Internet but I couldn't find a solution.

So how do I use the setData() method in a cypress test?


Solution

  • I don't think this is completely robust, but it's a reasonable starting point.

    cy.visit('https://ckeditor.com/ckeditor-4/demo/')
    
    // Note 1
    cy.window()
      .its('CKEDITOR.instances.ckdemoarticle', { timeout: 10_000 })
      .should('exist')
    
    // Note 2
    cy.get('iframe')
      .eq(0)
      .its('0.contentDocument.body')
      .should('contain', 'Essential things to think about')
    
    // Note 3
    cy.window().then(win => {
      console.log(win.CKEDITOR.instances.ckdemoarticle)
      win.CKEDITOR.instances.ckdemoarticle.setData(
        '<p>Some other editor data.</p>',
        {
          callback: function () {
            console.log('callback', this.checkDirty())
            this.checkDirty() // true
          },
        }
      )
    })
    
    // Note 4
    cy.get('iframe')
      .eq(0)
      .its('0.contentDocument.body')
      .should('contain', 'Some other editor data')
    

    Notes

    1. Waiting for the instance to exist (after visit)

    2. Verifying the current contents - seems to be required before invoking setData(), maybe it's just putting the editor into active mode (a click may also work)

    3. Invoke the setData() method. Note the instance name ckdemoarticle will be different for a different page.

    4. Verify the new text, if for no other reason than to prevent the test terminating before the app has re-rendered the editor.

    I haven't had a chance to explore all aspects, but it seems like a good starting test.

    enter image description here