Skip to content

feat: allow setValue to set values to contenteditable divs #2671

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

Tardigrada777
Copy link

@Tardigrada777 Tardigrada777 commented Jun 7, 2025

Implements #2390

Support setValue for contenteditable Elements

Summary

This PR extends the DOMWrapper.setValue method to support elements with the contenteditable attribute (such as <div contenteditable="true">). Previously, setValue was only applicable to form inputs, textareas, and selects. With this change, users can now easily set the inner HTML of contenteditable elements in their tests, and trigger the expected input and change events.

Details

  • New logic in setValue:
    When called on a DIV with the contenteditable attribute, setValue updates the element’s innerHTML, triggers both input and change events, and supports any value (object values will be stringified).
  • Error handling:
    If setValue is called on an unsupported element, an error is still thrown as before.
  • Tests:
    Added a dedicated test case to verify that setValue properly updates a contenteditable element’s inner HTML and triggers the appropriate events.

Motivation

Rich text editors and other contenteditable-based components are common in modern web apps. This enhancement allows for more robust and expressive testing of these components, improving DX and test reliability.

Example Usage

const wrapper = mount(Comp)
const editable = wrapper.find('div[contenteditable]')
await editable.setValue('<b>Bold</b>')
expect(editable.element.innerHTML).toBe('<b>Bold</b>')

Copy link

netlify bot commented Jun 7, 2025

Deploy Preview for vue-test-utils-docs ready!

Name Link
🔨 Latest commit ec401ab
🔍 Latest deploy log https://app.netlify.com/projects/vue-test-utils-docs/deploys/6843e2c4a987af0008eb40d2
😎 Deploy Preview https://deploy-preview-2671--vue-test-utils-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link
Member

@cexbrayat cexbrayat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR!

@@ -136,6 +136,14 @@ export class DOMWrapper<NodeType extends Node> extends BaseWrapper<NodeType> {
this.trigger('input')
// trigger `change` for `v-model.lazy`
return this.trigger('change')
} else if (tagName === 'DIV' && this.attributes().contenteditable) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK contenteditable is available on all tags, not only on divs

and the presence of the attribute might not be enough, as I think in <div contenteditable="true"><div id="inner"></div></div>, #inner is also editable.

I think using the property isContentEditable might be more reliable

expect(onInput).toHaveBeenCalledTimes(1)
expect(onChange).toHaveBeenCalledTimes(1)
})
})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be great to have more tests, with other elements than div, other values than true, nested elements with parents that are editable or not, etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants