_ = require 'underscore' React = require 'react/addons' TimeOverride = require '../../time-override' NylasTestUtils = require '../../nylas-test-utils' {Contenteditable} = require 'nylas-component-kit' ### Public: Easily test contenteditable interactions Create a new instance of this on each test. It will render a new Contenteditable into the document wrapped around a class that can keep track of its state. For example ```coffee beforeEach -> @ce = new ContenteditableTestHarness it "can create an ordered list", -> @ce.keys ['1', '.', ' '] @ce.expectHTML "
" @ce.expectSelection (dom) -> node: dom.querySelectorAll("li")[0] afterEach -> @ce.cleanup() ``` **Be sure to call `cleanup` after each test** ### class ContenteditableTestHarness constructor: ({@props, @initialValue}={}) -> @props ?= {} @initialValue ?= "" @wrap = NylasTestUtils.renderIntoDocument( ) cleanup: -> NylasTestUtils.removeFromDocument(@wrap) # We send keys to spectron one at a time. We also need ot use a "real" # setTimeout since Spectron is completely outside of the mocked setTimeouts # that we setup. We still `advanceClock` to clear any components or Promises # that need to run inbetween keystrokes. keys: (keyStrokes=[]) -> new Promise (resolve, reject) => TimeOverride.disableSpies() @getDOM().focus() timeout = 0 KEY_DELAY = 1000 keyStrokes.forEach (key) -> window.setTimeout -> NylasEnv.spectron.client.keys([key]) advanceClock(KEY_DELAY) , timeout timeout += KEY_DELAY window.setTimeout -> resolve() , timeout + KEY_DELAY expectHTML: (expectedHTML) -> expect(@wrap.state.value).toBe expectedHTML expectSelection: (callback) -> expectSel = callback(@getDOM()) anchorNode = expectSel.anchorNode ? expectSel.node ? "No anchorNode found" focusNode = expectSel.focusNode ? expectSel.node ? "No focusNode found" anchorOffset = expectSel.anchorOffset ? expectSel.offset ? 0 focusOffset = expectSel.focusOffset ? expectSel.offset ? 0 selection = document.getSelection() expect(selection.anchorNode).toBe anchorNode expect(selection.focusNode).toBe focusNode expect(selection.anchorOffset).toBe anchorOffset expect(selection.focusOffset).toBe focusOffset getDOM: -> React.findDOMNode(@wrap.refs["ceWrap"].refs["contenteditable"]) class Wrap extends React.Component @displayName: "wrap" constructor: (@props) -> @state = value: @props.initialValue render: -> userOnChange = @props.ceProps.onChange ? -> props = _.clone(@props.ceProps) props.onChange = (event) => userOnChange(event) @onChange(event) props.value = @state.value props.ref = "ceWrap" onChange: (event) -> @setState value: event.target.value componentDidMount: -> @refs.ceWrap.focus() module.exports = ContenteditableTestHarness