From c19d99e9e247c5c949865efbcbdc0f7f29030924 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 4 Feb 2015 11:40:21 -0800 Subject: [PATCH] Add integration test for starting atom w/ different arguments --- package.json | 1 + spec/integration/helpers/atom-launcher.sh | 36 ++++++++++ spec/integration/startup-spec.coffee | 85 +++++++++++++++++++++++ spec/spec-helper.coffee | 4 +- 4 files changed, 124 insertions(+), 2 deletions(-) create mode 100755 spec/integration/helpers/atom-launcher.sh create mode 100644 spec/integration/startup-spec.coffee diff --git a/package.json b/package.json index 346be5dd6..43fd11132 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "scoped-property-store": "^0.16.2", "scrollbar-style": "^2.0.0", "season": "^5.1.2", + "selenium-webdriver": "^2.44.0", "semver": "2.2.1", "serializable": "^1", "service-hub": "^0.2.0", diff --git a/spec/integration/helpers/atom-launcher.sh b/spec/integration/helpers/atom-launcher.sh new file mode 100755 index 000000000..c29a209b4 --- /dev/null +++ b/spec/integration/helpers/atom-launcher.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# This script wraps the `Atom` binary, allowing the `chromedriver` server to +# execute it with positional arguments. `chromedriver` only allows 'switches' +# to be specified when starting a browser, not positional arguments, so this +# script accepts two special switches: +# +# * `atom-path` The path to the `Atom` binary +# * `atom-args` A space-separated list of positional arguments to pass to Atom. +# +# Any other switches will be passed through to `Atom`. + +atom_path="" +atom_switches=() +atom_args=() + +for arg in "$@"; do + case $arg in + --atom-path=*) + atom_path="${arg#*=}" + ;; + + --atom-args=*) + atom_args_string="${arg#*=}" + for atom_arg in $atom_args_string; do + atom_args+=($atom_arg) + done + ;; + + *) + atom_switches+=($arg) + ;; + esac +done + +exec $atom_path "${atom_switches[@]}" "${atom_args[@]}" diff --git a/spec/integration/startup-spec.coffee b/spec/integration/startup-spec.coffee new file mode 100644 index 000000000..83b8e89f2 --- /dev/null +++ b/spec/integration/startup-spec.coffee @@ -0,0 +1,85 @@ +os = require "os" +fs = require "fs" +path = require "path" +remote = require "remote" +temp = require("temp").track() +{spawn, spawnSync} = require "child_process" +{Builder, By} = require("selenium-webdriver") + +AtomPath = remote.process.argv[0] +AtomLauncherPath = path.join(__dirname, "helpers", "atom-launcher.sh") +SocketPath = path.join(os.tmpdir(), "atom-integration-test.sock") +ChromeDriverPort = 9515 + +describe "Starting Atom", -> + if spawnSync("type", ["-P", "chromedriver"]).status isnt 0 + console.log "Skipping integration tests because the `chromedriver` executable was not found." + return + + [chromeDriver, driver, tempDirPath] = [] + + beforeEach -> + tempDirPath = temp.mkdirSync("empty-dir") + chromeDriver = spawn "chromedriver", ["--verbose", "--port=#{ChromeDriverPort}"] + + # Uncomment to see chromedriver debug output + # chromeDriver.stderr.on "data", (d) -> console.log(d.toString()) + + afterEach -> + waitsForPromise -> driver.quit().thenFinally(-> chromeDriver.kill()) + + startAtom = (args=[]) -> + driver = new Builder() + .usingServer("http://localhost:#{ChromeDriverPort}") + .withCapabilities( + chromeOptions: + binary: AtomLauncherPath + args: [ + "atom-path=#{AtomPath}" + "atom-args=#{args.join(" ")}" + "dev" + "safe" + "user-data-dir=#{temp.mkdirSync('integration-spec-')}" + "socket-path=#{SocketPath}" + ] + ) + .forBrowser('atom') + .build() + + waitsForPromise -> + driver.wait -> + driver.getTitle().then (title) -> title.indexOf("Atom") >= 0 + + describe "when given the name of a file that doesn't exist", -> + beforeEach -> + startAtom([path.join(tempDirPath, "new-file")]) + + it "opens a new window with an empty text editor", -> + waitsForPromise -> + driver.executeScript(-> atom.workspace.getActiveTextEditor().getText()).then (text) -> + expect(text).toBe("") + + driver.findElement(By.tagName("atom-text-editor")).sendKeys("Hello world!") + + driver.executeScript(-> atom.workspace.getActiveTextEditor().getText()).then (text) -> + expect(text).toBe("Hello world!") + + describe "when given the name of a file that exists", -> + beforeEach -> + existingFilePath = path.join(tempDirPath, "existing-file") + fs.writeFileSync(existingFilePath, "This was already here.") + startAtom([existingFilePath]) + + it "opens a new window with a text editor for the given file", -> + waitsForPromise -> + driver.executeScript(-> atom.workspace.getActiveTextEditor().getText()).then (text) -> + expect(text).toBe("This was already here.") + + describe "when given the name of a directory that exists", -> + beforeEach -> + startAtom([tempDirPath]) + + it "opens a new window no text editors open", -> + waitsForPromise -> + driver.executeScript(-> atom.workspace.getActiveTextEditor()).then (editor) -> + expect(editor).toBeNull() diff --git a/spec/spec-helper.coffee b/spec/spec-helper.coffee index 4c3c4c71b..1c5348594 100644 --- a/spec/spec-helper.coffee +++ b/spec/spec-helper.coffee @@ -305,13 +305,13 @@ window.waitsForPromise = (args...) -> window.waitsFor timeout, (moveOn) -> promise = fn() if shouldReject - promise.catch(moveOn) + (promise.catch ? promise.thenCatch).call(promise, moveOn) promise.then -> jasmine.getEnv().currentSpec.fail("Expected promise to be rejected, but it was resolved") moveOn() else promise.then(moveOn) - promise.catch (error) -> + (promise.catch ? promise.thenCatch).call promise, (error) -> jasmine.getEnv().currentSpec.fail("Expected promise to be resolved, but it was rejected with #{jasmine.pp(error)}") moveOn()