diff --git a/package.json b/package.json index db5526861..2a8aa9e12 100644 --- a/package.json +++ b/package.json @@ -65,14 +65,12 @@ "service-hub": "^0.2.0", "source-map-support": "^0.3.2", "space-pen": "3.8.2", - "spectron": "0.34.1", "spellchecker": "^3.1.2", "sqlite3": "https://github.com/mapbox/node-sqlite3/archive/v3.1.1.tar.gz", "temp": "^0.8", "theorist": "^1.0", "underscore": "^1.8", - "underscore.string": "^3.0", - "webdriverio": "3.2.6" + "underscore.string": "^3.0" }, "packageDependencies": {}, "private": true, diff --git a/spec/components/contenteditable/contenteditable-test-harness.cjsx b/spec/components/contenteditable/contenteditable-test-harness.cjsx deleted file mode 100644 index 45093211a..000000000 --- a/spec/components/contenteditable/contenteditable-test-harness.cjsx +++ /dev/null @@ -1,110 +0,0 @@ -_ = 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 diff --git a/spec/components/contenteditable/list-manager-spec.coffee b/spec/components/contenteditable/list-manager-spec.coffee deleted file mode 100644 index ff6924d56..000000000 --- a/spec/components/contenteditable/list-manager-spec.coffee +++ /dev/null @@ -1,122 +0,0 @@ -ContenteditableTestHarness = require './contenteditable-test-harness' - -return unless NylasEnv.inIntegrationSpecMode() - -xdescribe "ListManager", -> - beforeEach -> - # console.log "--> Before each" - @ce = new ContenteditableTestHarness - # div = document.querySelector("div[contenteditable]") - # console.log div - # console.log div?.innerHTML - # console.log "Done before each" - - afterEach -> - # console.log "<-- After each" - @ce.cleanup() - - it "Creates ordered lists", -> waitsForPromise => - @ce.keys(['1', '.', 'Space']).then => - # console.log "Keys typed" - @ce.expectHTML "
" - @ce.expectSelection (dom) -> - node: dom.querySelectorAll("li")[0] - - it "Undoes ordered list creation with backspace", -> waitsForPromise => - @ce.keys(['1', '.', 'Space', 'Back space']).then => - @ce.expectHTML "1. " - @ce.expectSelection (dom) -> - node: dom.childNodes[0] - offset: 3 - - it "Creates unordered lists with star", -> waitsForPromise => - @ce.keys(['*', 'Space']).then => - @ce.expectHTML "" - @ce.expectSelection (dom) -> - node: dom.querySelectorAll("li")[0] - - it "Undoes unordered list creation with backspace", -> - aitsForPromise => - @ce.keys(['*', 'Space', 'Back space']).then => - @ce.expectHTML "* " - @ce.expectSelection (dom) -> - node: dom.childNodes[0] - offset: 2 - - it "Creates unordered lists with dash", -> waitsForPromise => - @ce.keys(['-', 'Space']).then => - @ce.expectHTML "" - @ce.expectSelection (dom) -> - node: dom.querySelectorAll("li")[0] - - it "Undoes unordered list creation with backspace", -> - waitsForPromise => - @ce.keys(['-', 'Space', 'Back space']).then => - @ce.expectHTML "- " - @ce.expectSelection (dom) -> - node: dom.childNodes[0] - offset: 2 - - it "create a single item then delete it with backspace", -> - waitsForPromise => - @ce.keys(['-', 'Space', 'a', 'Left arrow', 'Back space']).then => - @ce.expectHTML "a" - @ce.expectSelection (dom) -> - node: dom.childNodes[0] - offset: 0 - - it "create a single item then delete it with tab", -> - waitsForPromise => - @ce.keys(['-', 'Space', 'a', 'Shift', 'Tab']).then => - @ce.expectHTML "a" - @ce.expectSelection (dom) -> dom.childNodes[0] - node: dom.childNodes[0] - offset: 1 - - describe "when creating two items in a list", -> - beforeEach -> - @twoItemKeys = ['-', 'Space', 'a', 'Return', 'b'] - - it "creates two items with enter at end", -> waitsForPromise => - @ce.keys(@twoItemKeys).then => - @ce.expectHTML "" - @ce.expectSelection (dom) -> - node: dom.querySelectorAll('li')[1].childNodes[0] - offset: 1 - - xit "backspace from the start of the 1st item outdents", -> - @ce.keys @twoItemKeys.concat ['left', 'up', 'backspace'] - - xit "backspace from the start of the 2nd item outdents", -> - @ce.keys @twoItemKeys.concat ['left', 'backspace'] - - xit "shift-tab from the start of the 1st item outdents", -> - @ce.keys @twoItemKeys.concat ['left', 'up', 'shift-tab'] - - xit "shift-tab from the start of the 2nd item outdents", -> - @ce.keys @twoItemKeys.concat ['left', 'shift-tab'] - - xit "shift-tab from the end of the 1st item outdents", -> - @ce.keys @twoItemKeys.concat ['up', 'shift-tab'] - - xit "shift-tab from the end of the 2nd item outdents", -> - @ce.keys @twoItemKeys.concat ['shift-tab'] - - xit "backspace from the end of the 1st item doesn't outdent", -> - @ce.keys @twoItemKeys.concat ['up', 'backspace'] - - xit "backspace from the end of the 2nd item doesn't outdent", -> - @ce.keys @twoItemKeys.concat ['backspace'] - - xdescribe "multi-depth bullets", -> - it "creates multi level bullet when tabbed in", -> - @ce.keys ['-', ' ', 'a', 'tab'] - - it "creates multi level bullet when tabbed in", -> - @ce.keys ['-', ' ', 'tab', 'a'] - - it "returns to single level bullet on backspace", -> - @ce.keys ['-', ' ', 'a', 'tab', 'left', 'backspace'] - - it "returns to single level bullet on shift-tab", -> - @ce.keys ['-', ' ', 'a', 'tab', 'shift-tab'] diff --git a/spec/jasmine-helper.coffee b/spec/jasmine-helper.coffee index e8c4cec28..9612c154e 100644 --- a/spec/jasmine-helper.coffee +++ b/spec/jasmine-helper.coffee @@ -43,22 +43,16 @@ module.exports.runSpecSuite = (specSuite, logFile, logErrors=true) -> NylasEnv.initialize() - # Tests that run under an integration environment need Spectron to be - # asynchronously setup and connected to the Selenium API before proceeding. - # Once setup, one can test `NylasEnv.inIntegrationSpecMode()` - # - # This safely works regardless if Spectron is loaded. - NylasEnv.setupSpectron().finally -> - require specSuite + require specSuite - jasmineEnv = jasmine.getEnv() - jasmineEnv.addReporter(reporter) - jasmineEnv.addReporter(timeReporter) - jasmineEnv.setIncludedTags([process.platform]) + jasmineEnv = jasmine.getEnv() + jasmineEnv.addReporter(reporter) + jasmineEnv.addReporter(timeReporter) + jasmineEnv.setIncludedTags([process.platform]) - $('body').append $$ -> @div id: 'jasmine-content' + $('body').append $$ -> @div id: 'jasmine-content' - jasmineEnv.execute() + jasmineEnv.execute() disableFocusMethods = -> ['fdescribe', 'ffdescribe', 'fffdescribe', 'fit', 'ffit', 'fffit'].forEach (methodName) -> diff --git a/spec_integration/contenteditable-integration-spec.es6 b/spec_integration/contenteditable-integration-spec.es6 index d4db223d8..425734dca 100644 --- a/spec_integration/contenteditable-integration-spec.es6 +++ b/spec_integration/contenteditable-integration-spec.es6 @@ -1,7 +1,7 @@ import {N1Launcher} from './integration-helper' import ContenteditableTestHarness from './contenteditable-test-harness.es6' -fdescribe('Contenteditable Integration Spec', function() { +describe('Contenteditable Integration Spec', function() { beforeAll((done)=>{ this.app = new N1Launcher(["--dev"]); this.app.popoutComposerWindowReady().finally(done); @@ -77,23 +77,53 @@ fdescribe('Contenteditable Integration Spec', function() { }).then(done).catch(done.fail) }); - // it("create a single item then delete it with backspace", (done) => { - // this.ce.test({ - // keys: ['-', 'Space', 'a', 'Left arrow', 'Back space'], - // expectedHTML: "a
", - // expectedSelectionResolver: (dom) => { - // return {node: dom.childNodes[0], offset: 0} } - // }).then(done).catch(done.fail) - // }); - // - // it("create a single item then delete it with tab", (done) => { - // this.ce.test({ - // keys: ['-', 'Space', 'a', 'Shift', 'Tab'], - // expectedHTML: "a
", - // expectedSelectionResolver: (dom) => { - // return {node: dom.childNodes[0], offset: 1} } - // }).then(done).catch(done.fail) - // }); + // describe "when creating two items in a list", -> + // beforeEach -> + // @twoItemKeys = ['-', 'Space', 'a', 'Return', 'b'] + // + // it "creates two items with enter at end", -> waitsForPromise => + // @ce.keys(@twoItemKeys).then => + // @ce.expectHTML "" + // @ce.expectSelection (dom) -> + // node: dom.querySelectorAll('li')[1].childNodes[0] + // offset: 1 + // + // xit "backspace from the start of the 1st item outdents", -> + // @ce.keys @twoItemKeys.concat ['left', 'up', 'backspace'] + // + // xit "backspace from the start of the 2nd item outdents", -> + // @ce.keys @twoItemKeys.concat ['left', 'backspace'] + // + // xit "shift-tab from the start of the 1st item outdents", -> + // @ce.keys @twoItemKeys.concat ['left', 'up', 'shift-tab'] + // + // xit "shift-tab from the start of the 2nd item outdents", -> + // @ce.keys @twoItemKeys.concat ['left', 'shift-tab'] + // + // xit "shift-tab from the end of the 1st item outdents", -> + // @ce.keys @twoItemKeys.concat ['up', 'shift-tab'] + // + // xit "shift-tab from the end of the 2nd item outdents", -> + // @ce.keys @twoItemKeys.concat ['shift-tab'] + // + // xit "backspace from the end of the 1st item doesn't outdent", -> + // @ce.keys @twoItemKeys.concat ['up', 'backspace'] + // + // xit "backspace from the end of the 2nd item doesn't outdent", -> + // @ce.keys @twoItemKeys.concat ['backspace'] + // + // xdescribe "multi-depth bullets", -> + // it "creates multi level bullet when tabbed in", -> + // @ce.keys ['-', ' ', 'a', 'tab'] + // + // it "creates multi level bullet when tabbed in", -> + // @ce.keys ['-', ' ', 'tab', 'a'] + // + // it "returns to single level bullet on backspace", -> + // @ce.keys ['-', ' ', 'a', 'tab', 'left', 'backspace'] + // + // it "returns to single level bullet on shift-tab", -> + // @ce.keys ['-', ' ', 'a', 'tab', 'shift-tab'] }); diff --git a/spec_integration/integrated-unit-spec.es6 b/spec_integration/integrated-unit-spec.es6 deleted file mode 100644 index 1c2ad5300..000000000 --- a/spec_integration/integrated-unit-spec.es6 +++ /dev/null @@ -1,36 +0,0 @@ -import {N1Launcher} from './integration-helper' - -// Some unit tests, such as the Contenteditable specs need to be run with -// Spectron availble in the environment. -describe('Integrated Unit Tests', function() { - beforeAll((done)=>{ - // Boot in dev mode with no arguments - this.app = new N1Launcher(["--test=window"]); - this.app.start().then(done).catch(done) - this.originalTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL - jasmine.DEFAULT_TIMEOUT_INTERVAL = 5*60*1000 // 5 minutes - }); - - afterAll((done)=> { - jasmine.DEFAULT_TIMEOUT_INTERVAL = this.originalTimeoutInterval - if (this.app && this.app.isRunning()) { - this.app.stop().then(done); - } else { - done() - } - }); - - it("Passes all integrated unit tests", (done)=> { - var client = this.app.client - client.waitForExist(".specs-complete", jasmine.UNIT_TEST_TIMEOUT) - .then(()=>{ return client.getHTML(".specs-complete .message") }) - .then((results)=>{ - expect(results).toMatch(/0 failures/) - }).then(()=>{ return client.getHTML(".plain-text-output") }) - .then((errorOutput)=>{ - expect(errorOutput).toBe('
')
-      done()
-    }).catch(done)
-  });
-
-});
diff --git a/src/nylas-env.coffee b/src/nylas-env.coffee
index 837969a4e..71ed2e1a9 100644
--- a/src/nylas-env.coffee
+++ b/src/nylas-env.coffee
@@ -223,52 +223,6 @@ class NylasEnvConstructor extends Model
     window.onbeforeunload = => @_unloading()
     @_unloadCallbacks = []
 
-  # Some unit tests require access to the Selenium web driver APIs as exposed
-  # by Spectron/Chromedriver. The app must be booted by Spectron as is done in the `run-integration-tests` task. Once Spectron boots the app, it will expose a RESTful API
-  #
-  # The Selenium API spec is here: https://code.google.com/p/selenium/wiki/JsonWireProtocol
-  #
-  # The Node wrapper for that API is provided by webdriver: http://webdriver.io/api.html
-  #
-  # Spectron wraps webdriver (in its `client` property) and adds additional methods: https://github.com/kevinsawicki/spectron
-  #
-  # Spectron requests that Selenium use Chromedriver
-  # https://sites.google.com/a/chromium.org/chromedriver/home to interface
-  # with the app, but points the binary at Electron.
-  #
-  # Since this code here is "inside" the booted process, we have no way of
-  # directly accessing the client from the test runner. However, we can still
-  # connect directly to the Selenium server to control ourself.
-  #
-  # We unfortunately can't create a new session with Selenium, because we
-  # won't be connected to the correct process (us!). Instead we need to
-  # inspect the existing sessions and use the existing one instead.
-  #
-  # We then manually setup the WebDriver session, and add in the extra
-  # spectron APIs via `Spectron.Application::addCommands`.
-  #
-  # http://webdriver.io/api/protocol/windowHandles.html
-  # https://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/element/:id/value
-  setupSpectron: ->
-    options =
-      host: "127.0.0.1"
-      port: 9515
-    SpectronApp = require('spectron').Application
-    @spectron = new SpectronApp
-    WebDriver = require('webdriverio')
-    @spectron.client = new WebDriver.remote(options)
-    @spectron.addCommands()
-    @spectron.client.sessions().then ({value}) =>
-      {sessionId, capabilities} = value[0]
-      @spectron.client.requestHandler.sessionID = sessionId
-      # https://github.com/webdriverio/webdriverio/blob/master/lib/protocol/init.js
-      @spectron.client.sessionID = sessionId
-      @spectron.client.capabilities = capabilities
-      @spectron.client.desiredCapabilities = capabilities
-
-  inIntegrationSpecMode: ->
-    @inSpecMode() and @spectron?.client?.sessionID
-
   # Start our error reporting to the backend and attach error handlers
   # to the window and the Bluebird Promise library, converting things
   # back through the sourcemap as necessary.