javascripttypescriptcypressckeditorckeditor4.x

Using Cypress.IO to to setData on CKeditor 4


I'm using cypress to automate my project. I have CKeditor4. So I tried below 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.

Tried everything available in internet but couldn't find a solution in Cypress.IO.

So how to use setData method using cypress code


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