reactjs - @foreachbe/cypress-tinymce Cypress için TinyMCE paketi, TypeScript ile editörler örneği için her zaman tanımsız dönüyor


TypeScript kullanarak bir React JS uygulaması geliştiriyorum. Uygulamada bir formda TinyMCE editörünü kullanıyorum. Ayrıca TypeScript ile Cypress kullanarak entegrasyon testleri yazıyorum. Şu anda Cypress'lerde TypeScript kullanarak TinyMCE editör değerini ayarlamakta sorun yaşıyorum. Cypress'te TinyMCE editörünü manipüle etmek için bu kütüphaneyi kullanıyorum, https://github.com/ForeachOS/cypress-tinymce.

Bu benim React JS TinyMCE editör kodum.

import React, { FC } from 'react'
import { Editor } from '@tinymce/tinymce-react'

interface RichEditorFieldProps {
    id: string
    name?: string
    value?: string
    onChange: (fieldName: string, value: string) => void
}

const RichEditorField: FC<RichEditorFieldProps> = (
    props: RichEditorFieldProps
) => {
    const getFieldName = () => {
        return props.name ? props.name : props.id
    }

    return (
        <div cy-data-id={props.id} className={'rich-editor-field-container'}>
            <Editor
                id={props.id}
                apiKey={'zjf0nctg4gmjj0a5u5uxm7pcrs0ka4hwcuxzskhxh5hauugf'}
                value={props.value ?? ''}
                onEditorChange={(content) => {
                    props.onChange(getFieldName(), content)
                }}
            />
        </div>
    )
}

O bileşeni şu şekilde render ediyorum:

<FormRichEditorField
                            value={formik.values.specification}
                            label={'Specification'}
                            error={
                                formik.touched.specification &&
                                formik.errors.specification
                            }
                            id={'specification'}
                            onChange={formik.setFieldValue}
                        />

Vurgulamak istediğim şey, editörün kimliğinin specification olduğudur.

Bunu Cypress'te test etmek için, bahsettiğim paketi kurdum, https://github.com/ForeachOS/cypress-tinymce.

Paketi kurduktan ve support/index.ts dosyasına aktardıktan sonra, fonksiyonu şu şekilde çağıramıyorum:

cy.setTinyMceContent('specification', 'This is the new content');

TypeScript ile uyumlu hale getirmek için aşağıdaki kodu eklemem gerekiyor:

declare namespace Cypress {
    interface Chainable<Subject = any> {
        setTinyMceContent(tinyMceId: string, content: any): void
    }
}

Sonra Cypress testimde TinyMCE editör alanının değerini şu şekilde ayarladım:

cy.setTinyMceContent('specification', 'This is testing')

Testi çalıştırdığımda aşağıdaki hatayı alıyorum:

Cannot read properties of undefined (reading 'specification')

Kodumda ne yanlış ve bunu nasıl düzeltebilirim?

Cevap #1

cypress-tinymce paketi oldukça eski görünüyor. En son sürüm 6 tinyMCE'de editors özelliği yok.

Aşağıdaki şu ana kadar sahip olduğum en iyi şey. Editörün açılmasını beklemeniz gereken birkaç yer var.

İkincisi mevcut metin içeriğini bekliyor, bu iyi değil çünkü çok özel. Bunu yapmanın daha iyi bir yolunu henüz bulamadım.

@WaiYanHein yorumundan güncellendi

/// <reference types="cypress" />

Cypress.Commands.add('setTinyMceContent', (tinyMceId: string, content: any) => {
  
  cy.window().should('have.property', 'tinymce')   // wait for tinyMCE

  cy.wait(1000).then(() => {   // wait for editor to be ready

    const win = cy.state('window')
    const editor = win.tinymce.EditorManager.get() 
      .filter((editor: any) => editor.id === fieldId)[0] 

    editor2.setContent(content, { format: 'text' });
  })
})

it('adds some text to tinyMCE', () => {

  cy.visit('http://localhost:3001')

  cy.setTinyMceContent('specification', 'This is the new content')

  cy.window().then(win => {
    cy.wrap(win.tinymce.activeEditor.getContent({ format: 'text'}))
      .should('eq', 'This is the new content')                      // ✅ passes
  })
});

React uygulaması içeriği kontrol ediyor, metnin "Bu yeni içerik" olarak değiştiğini görüp sonra tekrar "Bazı metin" olarak geri döndüğünü görebilirsiniz.

Bence bu, onChange() olayının tetiklenmesi sonucu meydana geliyor; bu olay, bileşeni yeniden render ediyor ve onu tekrar App'in metnine ayarlıyor.

Bundan dolayı, React uygulamasını doğrudan tinyMCE API'sine yaklaşmak yerine uygulama eylemleri aracılığıyla kontrol etmek daha iyi olabilir. Bu, testlerinizin hedeflerine bağlıdır.

Cevap #2

Cypress.Commands.add(
  "setTinyMceContent",
  (tinyMceId = "tiny-mce", content = "") => {
    cy.window().should("have.property", "tinymce"); // wait for tinyMCE
    cy.wait(500);
    cy.window().then((win) => {
      const editor = win.tinymce.EditorManager.get().find(
        (edtr) => edtr.id === tinyMceId
      );

      editor.setContent(content, { format: "text" });
      cy.wait(250);
      cy.wrap(editor.getContent({ format: "text" })).should("eq", content);
    });
  }
);

Bu, v6 ile benim için işe yarayan şey.