最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to addtype a text in CKeditor (v4) in Cypress Automation?Or any Method to Set The Value for Ckeditor in Cypress

programmeradmin0浏览0评论

I am using this method in mands.js

Cypress.Commands.add(
'iframeLoaded', { prevSubject: 'element' },
($iframe) => {
    const contentWindow = $iframe.prop('contentWindow')
    return new Promise(resolve => {
        if (
            contentWindow &&
            contentWindow.document.readyState === 'plete'
        ) {
            resolve(contentWindow)
        } else {
            $iframe.on('load', () => {
                resolve(contentWindow)
            })
        }
    })
})
Cypress.Commands.add(
'getInDocument', { prevSubject: 'document' },
(document, selector) => Cypress.$(selector, document))

I need your Suggestions or any other method to solve the this problem.

Following code is working fine but nothing shows as output.

cy.get('iframe')
        .iframeLoaded()
        .its('document')
        .get('#cke_10_contents > .cke_wysiwyg_frame')
        .type("Text");

This is my Script & showing in the console 'Timed out retrying: expected '' to equal 'some new text'.

describe('demo', function() {
it('test', function() {


    cy.visit('https://automationtestname688296/create')
    cy.get('#email').type('[email protected]');
    cy.get('#password').type('test2020');
    cy.get('.checkmark').click().wait(2000);

    cy.get(':nth-child(6) > .form-control').contains('Login').click()
// I want to Enter Text in First Text Editor
.then(() => {

cy.get('iframe.cke_wysiwyg_frame')  // "cke_wysiwyg_frame" class is used here
  .iframeLoaded()                   // wait for the iframe to be loaded
  .then($frameWindow => {

    const win = cy.state('window'); // grab the window Cypress is testing
    const ckEditor = win.CKEDITOR;  // CKEditor has added itself to the window
    const instances = ckEditor.instances;  // can be multiple editors on the page

    const myEditor = Object.values(instances)
      .filter(instance => instance.id === 'cke_8')[0]; // select the instance by id

    // use CKEditor API to change the text
    myEditor.setData('<h1>some new text</h1>'); 

    // Verify
    cy.wrap($frameWindow)
      .its('document')
      .its('body')
      .invoke('text')
      .should('eq', 'some new text')

})
})

I am using this method in mands.js

Cypress.Commands.add(
'iframeLoaded', { prevSubject: 'element' },
($iframe) => {
    const contentWindow = $iframe.prop('contentWindow')
    return new Promise(resolve => {
        if (
            contentWindow &&
            contentWindow.document.readyState === 'plete'
        ) {
            resolve(contentWindow)
        } else {
            $iframe.on('load', () => {
                resolve(contentWindow)
            })
        }
    })
})
Cypress.Commands.add(
'getInDocument', { prevSubject: 'document' },
(document, selector) => Cypress.$(selector, document))

I need your Suggestions or any other method to solve the this problem.

Following code is working fine but nothing shows as output.

cy.get('iframe')
        .iframeLoaded()
        .its('document')
        .get('#cke_10_contents > .cke_wysiwyg_frame')
        .type("Text");

This is my Script & showing in the console 'Timed out retrying: expected '' to equal 'some new text'.

describe('demo', function() {
it('test', function() {


    cy.visit('https://automationtestname688296/create')
    cy.get('#email').type('[email protected]');
    cy.get('#password').type('test2020');
    cy.get('.checkmark').click().wait(2000);

    cy.get(':nth-child(6) > .form-control').contains('Login').click()
// I want to Enter Text in First Text Editor
.then(() => {

cy.get('iframe.cke_wysiwyg_frame')  // "cke_wysiwyg_frame" class is used here
  .iframeLoaded()                   // wait for the iframe to be loaded
  .then($frameWindow => {

    const win = cy.state('window'); // grab the window Cypress is testing
    const ckEditor = win.CKEDITOR;  // CKEditor has added itself to the window
    const instances = ckEditor.instances;  // can be multiple editors on the page

    const myEditor = Object.values(instances)
      .filter(instance => instance.id === 'cke_8')[0]; // select the instance by id

    // use CKEditor API to change the text
    myEditor.setData('<h1>some new text</h1>'); 

    // Verify
    cy.wrap($frameWindow)
      .its('document')
      .its('body')
      .invoke('text')
      .should('eq', 'some new text')

})
})
Share Improve this question edited Dec 1, 2020 at 6:13 GHULAM NABI asked Nov 30, 2020 at 5:48 GHULAM NABIGHULAM NABI 5045 silver badges15 bronze badges 5
  • You can also give another method to resolve this issue – GHULAM NABI Commented Nov 30, 2020 at 5:54
  • 1 Can you post a screenshot of your Dom structure as well or if you have Public website that will help as well. – Alapan Das Commented Nov 30, 2020 at 7:51
  • <iframe src="" frameborder="0" class="cke_wysiwyg_frame cke_reset" style="width: 100%; height: 100%;" title="Rich Text Editor, editor2" tabindex="0" allowtransparency="true"></iframe> 2 – GHULAM NABI Commented Nov 30, 2020 at 11:00
  • 1 Thank you for posting your script, but it is the same as the one you posted first. You should really try it with the steps I have shown - change from .iframeLoaded() onwards, and make sure the id is correct (cke_8). – Richard Matsen Commented Dec 1, 2020 at 5:28
  • I have Tried your Script but It is showing Timed out retrying: expected '' to equal 'some new text'@RichardMatsen – GHULAM NABI Commented Dec 1, 2020 at 5:41
Add a ment  | 

6 Answers 6

Reset to default 8

I have a feeling there's more to this, but a basic test like this works with CKEditor v5

cy.visit('https://ckeditor./ckeditor-5/demo/')
  .then(() => {

    cy.get('.ck-content')
      .clear()
      .type('Hello CKEditor');

    cy.get('.ck-content')
      .invoke('text')
      .should('eq','Hello CKEditor')

  })

For CKEditor v4,

cy.visit('https://ckeditor./ckeditor-4/demo/')
  .then(() => {

    cy.get('iframe.cke_wysiwyg_frame')  // "cke_wysiwyg_frame" class is used here
      .iframeLoaded()                   // wait for the iframe to be loaded
      .then($frameWindow => {

        const win = cy.state('window'); // grab the window Cypress is testing
        const ckEditor = win.CKEDITOR;  // CKEditor has added itself to the window
        const instances = ckEditor.instances;  // can be multiple editors on the page

        const myEditor = Object.values(instances)
          .filter(instance => instance.id === 'cke_1')[0]; // select the instance by id

        // use CKEditor API to change the text
        myEditor.setData('<h1>some new text</h1>'); 

        // Verify
        cy.wrap($frameWindow)
          .its('document')
          .its('body')
          .invoke('text')
          .should('eq', 'some new text')

    })
  })

this worked for me:

    cy.get("iframe.cke_wysiwyg_frame").then(function($iframe) {
      const $body = $iframe.contents().find("body");
      console.log($body);
      cy.wrap($body[0]).type("Random text");
    }); 

May also require to add a waiter ahead of it to make sure the frame is fully loaded.

// Call out to the page window and use the CKEDITOR object

cy.window()

.then(win => { win.CKEDITOR.instances["html_body"].setData("

HTML body

"); });

This works consistently for me.

  1. Append the following to cypress/support/mands.js to get the functionality.

    Cypress.Commands.add('typeCkeditor', {
      prevSubject: true,
    }, (prevSubject, html) => {
     cy.get(prevSubject).invoke('attr', 'id').as('ckeditorInstance');
    
     cy.get('@ckeditorInstance').then((id) => {
       cy.state('window').CKEDITOR.instances[id].setData(html);
     });
    });
    
  2. Append the following to cypress/support/index.d.ts to get the code editor hints.

    /**
     * Types on CKeditor fields.
     * @param HTML
     */
    typeCkeditor(html:string): Chainable<any>
    
  3. Use it:

    cy.get('textarea-selector').typeCkeditor("Your message");
    

Note: the textarea selector should make reference to the hidden textarea where Ckeditor stores the HTML code, usually a few levels above the Ckeditor iframe.

This solution works for me with Ckeditor(v4).

cy.pause(); //wait for the editor to load pletely
cy.window().then((win) => {
            win.CKEDITOR.instances['editor1'].setData("HTML body") });

Here is the solution for Ckeditor(v4).Just add this custom mand in mand.js

Cypress.Commands.add('iframe', { prevSubject: 'element' }, ($iframe) => {
const $iframeDoc = $iframe.contents()
const findBody = () => $iframeDoc.find('body')

if ($iframeDoc.prop('readyState') === 'plete') return findBody()

return Cypress.Promise((resolve) => $iframe.on('load', () => 
resolve(findBody())))
});

Cypress.Commands.add(
    'iframeLoaded', { prevSubject: 'element' },
     ($iframe) => {
       const contentWindow = $iframe.prop('contentWindow')
       return new Promise(resolve => {
        if (
            contentWindow &&
            contentWindow.document.readyState === 'plete'
        ) {
            resolve(contentWindow)
        } else {
            $iframe.on('load', () => {
                resolve(contentWindow)
            })
        }
    })
})

Cypress.Commands.add(
   'getInDocument', { prevSubject: 'document' },
(document, selector) => Cypress.$(selector, document)
 )

Now, Copy the exact Selector of CkEditor and Access it like this code in your test:

cy.get('#cke_155_contents > .cke_wysiwyg_frame').first().then(frame => {
        const iframe = frame.contents();
        const body = iframe.find('body');
        body.attr('contenteditable', 'true');
        cy.wrap(body).type('Text Should be here.', { force: true })
    })
    cy.get('iframe.cke_wysiwyg_frame') // "cke_wysiwyg_frame" class is 
        .iframeLoaded() // wait for the iframe to be loaded
        .then($frameWindow => {
            const win = cy.state('window'); // grab the window Cypress
            const ckEditor = win.CKEDITOR; // CKEditor has added itself to 
            const instances = ckEditor.instances;//can be multiple editors
            const myEditor = Object.values(instances)
                .filter(instance => instance.id === 'cke_155')[0]; 
            // use CKEditor API to change the text
            myEditor.setData('<h1>Text Should be here.</h1>');
            // Verify
            cy.wrap($frameWindow)
                .its('document')
                .its('body')
                .invoke('text')
            cy.get('#high-submit').click()
        })

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论