How to type using cypress .type() inside the codemirror editor?
Asked Answered
T

4

9

I am writing some cypress test for the Codemirror Editor. I have use cypress to type in the input field.

I am trying to achieve the cy.type() in the CodeMirror Editor. The Data I have in codemirror is inside the span.

<pre class=" CodeMirror-line " role="presentation">
  <span role="presentation" style="padding-right: 0.1px;"> &lt; h1 &gt; Welcome to your web project canvas! &lt; /h1&gt;</span>
</pre> 

The cypress spec code

cy.get('pre.CodeMirror-line')
  .type('Cypress HTML Data')

I am not able to type some data using cypress.

I would appreciate if someone can help?

Tickler answered 26/3, 2019 at 17:20 Comment(0)
S
7

You're not targeting the correct element in your spec code. You're doing cy.get('pre.CodeMirror-line'), but a <pre> tag is not a cy.type()-able element.

You need to get the hidden CodeMirror <textarea> instead. This can be selected using .CodeMirror textarea. The following JS is a demo spec that works on codemirror.net:

describe('Codemirror', () => {
  it('can be tested using textarea', () => {
    cy.visit('https://codemirror.net/')
    // CodeMirror's editor doesn't let us clear it from the
    // textarea, but we can read the Window object and then
    // invoke `setValue` on the editor global
    cy.window().then(win => {
      win.editor.setValue("")
    })
    cy.get('.CodeMirror textarea')
    // we use `force: true` below because the textarea is hidden
    // and by default Cypress won't interact with hidden elements
      .type('test test test test', { force: true })
  })
})
Strum answered 26/3, 2019 at 17:36 Comment(8)
That's perfect Brillant Lad!Tickler
Hey @Zach Bloomquist How do you clear the editor? I have tried cy.get('.CodeMirror textarea') .clear()Tickler
@RahulThawal you'll have to access the global editor object and then setValue on it. I've updated the answer with an example that works on codemirror.net.Strum
Thank you! Awesome!Tickler
Alternatively you can do the following: cy.get('.CodeMirror-code').type(<your text>)Slider
A question on similar thread: How do I get text from the CodeMirror Editor? I found an answer on this question that shows how I can do it in the page's JS. #10285801 I am looking to do something in the Cypress test.Eddra
This did not work for me, I actually couldn't find the "editor" in the Window object when running CypressHookup
This might help @Eren555 #62012819Hookup
G
12

It is also possible to use invoke('text', 'some-text') to update the editor.

For example, on https://codemirror.net/try/

cy.visit('https://codemirror.net/try/');

cy.get('[role="textbox"]')
  .invoke('text')
  .should('match', /import {basicSetup, EditorView}/)

// edit the whole textbox
cy.get('[role="textbox"]')
  .invoke('text', 'using invoke to add text')

cy.get('[role="textbox"]')
  .should('have.text', 'using invoke to add text')

// now add a line and change it's text
cy.get('[role="textbox"]')
  .type('{enter}')

cy.get('.cm-activeLine')
  .invoke('text', 'adding a line')

cy.get('[role="textbox"]')
  .should('have.text', 'using invoke to add textadding a line')

enter image description here

Glassco answered 27/7 at 23:54 Comment(1)
I use this to test CodeMirror - using cm-activeline gives complete control of insert, update, delete operations.Litmus
S
7

You're not targeting the correct element in your spec code. You're doing cy.get('pre.CodeMirror-line'), but a <pre> tag is not a cy.type()-able element.

You need to get the hidden CodeMirror <textarea> instead. This can be selected using .CodeMirror textarea. The following JS is a demo spec that works on codemirror.net:

describe('Codemirror', () => {
  it('can be tested using textarea', () => {
    cy.visit('https://codemirror.net/')
    // CodeMirror's editor doesn't let us clear it from the
    // textarea, but we can read the Window object and then
    // invoke `setValue` on the editor global
    cy.window().then(win => {
      win.editor.setValue("")
    })
    cy.get('.CodeMirror textarea')
    // we use `force: true` below because the textarea is hidden
    // and by default Cypress won't interact with hidden elements
      .type('test test test test', { force: true })
  })
})
Strum answered 26/3, 2019 at 17:36 Comment(8)
That's perfect Brillant Lad!Tickler
Hey @Zach Bloomquist How do you clear the editor? I have tried cy.get('.CodeMirror textarea') .clear()Tickler
@RahulThawal you'll have to access the global editor object and then setValue on it. I've updated the answer with an example that works on codemirror.net.Strum
Thank you! Awesome!Tickler
Alternatively you can do the following: cy.get('.CodeMirror-code').type(<your text>)Slider
A question on similar thread: How do I get text from the CodeMirror Editor? I found an answer on this question that shows how I can do it in the page's JS. #10285801 I am looking to do something in the Cypress test.Eddra
This did not work for me, I actually couldn't find the "editor" in the Window object when running CypressHookup
This might help @Eren555 #62012819Hookup
S
1

A few updates for version 6.

  1. The editable element has a class of cm-content and a role of textbox.
  2. Typing into the element can pair brackets, so it's not practical to just type in a specific string in all cases.
  3. It's possible to paste.
  4. First select all the content and delete it to clear the field.
  const clipboardData = new DataTransfer();
  clipboardData.setData("text/plain", theStringToPasteIn);
  const pasteEvent = new ClipboardEvent("paste", {
    clipboardData
  });

  cy.get(`.cm-editor [role="textbox"]`)
    .type("{selectAll}{backspace}")
    .trigger("paste", pasteEvent);
Seng answered 3/4 at 2:48 Comment(0)
S
1

For the Codemirrow v6, I've managed to type in the contenteditable element using realType method

cy.findByRole('textbox').click().realType('Test');

Check out this issue in Cypress repo.

The realType method must be installed

npm install cypress-real-events

and added to your cypress/support/index.{js,ts}

import "cypress-real-events";
Sst answered 27/7 at 16:8 Comment(3)
The linked issue is about CKEditor not Codemirror.Battleplane
All modern code editors are using DOM elements with contenteditable flagSst
This is IMHO the only working solution at the moment for Cypress v13 and CodeMirror v6. Thanks!Shaveling

© 2022 - 2024 — McMap. All rights reserved.