test(contenteditable): add test harness

This commit is contained in:
Evan Morikawa 2015-12-01 18:49:40 -08:00
parent c3ecca2692
commit 21353031be
8 changed files with 190 additions and 20 deletions

View file

@ -2,7 +2,7 @@ ContenteditableTestHarness = require './contenteditable-test-harness'
return unless NylasEnv.inIntegrationSpecMode()
fdescribe "ListManager", ->
xdescribe "ListManager", ->
beforeEach ->
# console.log "--> Before each"
@ce = new ContenteditableTestHarness
@ -22,7 +22,7 @@ fdescribe "ListManager", ->
@ce.expectSelection (dom) ->
node: dom.querySelectorAll("li")[0]
ffit "Undoes ordered list creation with backspace", -> waitsForPromise =>
it "Undoes ordered list creation with backspace", -> waitsForPromise =>
@ce.keys(['1', '.', 'Space', 'Back space']).then =>
@ce.expectHTML "1. "
@ce.expectSelection (dom) ->
@ -35,7 +35,7 @@ fdescribe "ListManager", ->
@ce.expectSelection (dom) ->
node: dom.querySelectorAll("li")[0]
xit "Undoes unordered list creation with backspace", ->
it "Undoes unordered list creation with backspace", ->
aitsForPromise =>
@ce.keys(['*', 'Space', 'Back space']).then =>
@ce.expectHTML "* "

View file

@ -20,7 +20,10 @@ module.exports.runSpecSuite = (specSuite, logFile, logErrors=true) ->
else
remote.process.stdout.write(str)
if NylasEnv.getLoadSettings().exitWhenDone
if NylasEnv.getLoadSettings().showSpecsInWindow
N1SpecReporter = require './n1-spec-reporter'
reporter = new N1SpecReporter()
else if NylasEnv.getLoadSettings().exitWhenDone
reporter = new TerminalReporter
color: true
print: (str) ->

View file

@ -3,7 +3,7 @@ import {N1Launcher} from './integration-helper'
describe('Nylas Prod Bootup Tests', function() {
beforeAll((done)=>{
// Boot in dev mode with no arguments
this.app = new N1Launcher([]);
this.app = new N1Launcher(["--dev"]);
this.app.mainWindowReady().finally(done);
});

View file

@ -0,0 +1,74 @@
import Promise from 'bluebird'
import {N1Launcher} from './integration-helper'
import ContenteditableTestHarness from './contenteditable-test-harness.es6'
fdescribe('Contenteditable Integration Spec', function() {
beforeAll((done)=>{
console.log("----------- BEFORE ALL");
// Boot in dev mode with no arguments
this.app = new N1Launcher(["--dev"]);
this.app.popoutComposerWindowReady().finally(done);
});
beforeEach((done) => {
console.log("----------- BEFORE EACH");
this.ce = new ContenteditableTestHarness(this.app.client, expect)
this.ce.init().finally(done);
});
afterAll((done)=> {
if (this.app && this.app.isRunning()) {
this.app.stop().then(done);
} else {
done()
}
});
fit("Creates ordered lists", (done)=> {
console.log("RUNNING KEYS");
this.app.client.keys(["1", ".", "Space"]).then(()=>{
console.log("DONE FIRING KEYS");
e1 = this.ce.expectHTML("<ol><li>WOOO</li></ol>")
e2 = this.ce.expectSelection((dom) => {
return {node: dom.querySelectorAll("li")[0]}
})
return Promise.all(e1,e2)
}).catch((err)=>{ console.log("XXXX ERROR"); console.log(err); }).finally(done)
});
it("has main window visible", (done)=> {
this.app.client.isWindowVisible()
.then((result)=>{ expect(result).toBe(true) })
.finally(done)
});
it("has main window focused", (done)=> {
this.app.client.isWindowFocused()
.then((result)=>{ expect(result).toBe(true) })
.finally(done)
});
it("isn't minimized", (done)=> {
this.app.client.isWindowMinimized()
.then((result)=>{ expect(result).toBe(false) })
.finally(done)
});
it("doesn't have the dev tools open", (done)=> {
this.app.client.isWindowDevToolsOpened()
.then((result)=>{ expect(result).toBe(false) })
.finally(done)
});
it("has width", (done)=> {
this.app.client.getWindowWidth()
.then((result)=>{ expect(result).toBeGreaterThan(0) })
.finally(done)
});
it("has height", (done)=> {
this.app.client.getWindowHeight()
.then((result)=>{ expect(result).toBeGreaterThan(0) })
.finally(done)
});
});

View file

@ -0,0 +1,58 @@
import Promise from 'bluebird'
class ContenteditableTestHarness {
constructor(client, expect) {
this.expect = expect
this.client = client;
}
init() {
console.log("INIT TEST HARNESS");
return this.client.execute(() => {
ce = document.querySelector(".contenteditable")
ce.innerHTML = ""
ce.focus()
}).then(({value})=>{
console.log(value);
})
}
expectHTML(expectedHTML) {
console.log("EXPECTING HTML");
console.log(expectedHTML);
return this.client.execute((expect, arg2) => {
console.log(expect);
console.log(arg2);
ce = document.querySelector(".contenteditable")
expect(ce.innerHTML).toBe(expectedHTML)
return ce.innerHTML
}, this.expect, "FOOO").then(({value})=>{
console.log("GOT HTML VALUE");
console.log(value);
}).catch((err)=>{
console.log("XXXXXXXXXX GOT ERROR")
console.log(err);
})
}
expectSelection(callback) {
return this.client.execute(() => {
ce = document.querySelector(".contenteditable")
expectSel = callback(ce)
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()
this.expect(selection.anchorNode).toBe(anchorNode)
this.expect(selection.focusNode).toBe(focusNode)
this.expect(selection.anchorOffset).toBe(anchorOffset)
this.expect(selection.focusOffset).toBe(focusOffset)
})
}
}
module.exports = ContenteditableTestHarness

View file

@ -2,7 +2,7 @@ import {N1Launcher} from './integration-helper'
// Some unit tests, such as the Contenteditable specs need to be run with
// Spectron availble in the environment.
fdescribe('Integrated Unit Tests', function() {
describe('Integrated Unit Tests', function() {
beforeAll((done)=>{
// Boot in dev mode with no arguments
this.app = new N1Launcher(["--test=window"]);

View file

@ -11,14 +11,48 @@ class N1Launcher extends Application {
}
mainWindowReady() {
return this.windowReady(N1Launcher.mainWindowMatcher)
}
popoutComposerWindowReady() {
return this.windowReady(N1Launcher.mainWindowMatcher).then(() => {
return this.client.execute(()=>{
require('nylas-exports').Actions.composeNewBlankDraft();
})
}).then(()=>{
return N1Launcher.waitUntilMatchingWindowLoaded(this.client, N1Launcher.composerWindowMatcher).then((windowId)=>{
return this.client.window(windowId)
})
})
}
windowReady(matcher) {
// Wrap in a Bluebird promise so we have `.finally on the return`
return Promise.resolve(this.start().then(()=>{
return N1Launcher.waitUntilMainWindowLoaded(this.client).then((mainWindowId)=>{
return this.client.window(mainWindowId)
return N1Launcher.waitUntilMatchingWindowLoaded(this.client, matcher).then((windowId)=>{
return this.client.window(windowId)
})
}));
}
static mainWindowMatcher(client) {
return client.isExisting(".main-window-loaded").then((exists)=>{
if (exists) {return true} else {return false}
})
}
static composerWindowMatcher(client) {
return client.execute(()=>{
return NylasEnv.getLoadSettings().windowType;
}).then(({value})=>{
if(value === "composer") {
return client.isWindowVisible()
} else {
return false
}
})
}
static defaultNylasArgs() {
return ["--enable-logging", `--resource-path=${jasmine.NYLAS_ROOT_PATH}`]
}
@ -47,22 +81,22 @@ class N1Launcher extends Application {
//
// Returns a promise that resolves with the main window's ID once it's
// loaded.
static waitUntilMainWindowLoaded(client, lastCheck=0) {
var CHECK_EVERY = 1000
static waitUntilMatchingWindowLoaded(client, matcher, lastCheck=0) {
var CHECK_EVERY = 500
return new Promise((resolve, reject) => {
client.windowHandles().then(({value}) => {
return Promise.mapSeries(value, (windowId)=>{
return N1Launcher.switchAndCheckForMain(client, windowId)
return N1Launcher.switchAndCheckForMatch(client, windowId, matcher)
})
}).then((mainChecks)=>{
for (mainWindowId of mainChecks) {
if (mainWindowId) {return resolve(mainWindowId)}
}).then((windowIdChecks)=>{
for (windowId of windowIdChecks) {
if (windowId) {return resolve(windowId)}
}
var now = Date.now();
var delay = Math.max(CHECK_EVERY - (now - lastCheck), 0)
setTimeout(()=>{
N1Launcher.waitUntilMainWindowLoaded(client, now).then(resolve)
N1Launcher.waitUntilMatchingWindowLoaded(client, matcher, now).then(resolve)
}, delay)
}).catch((err) => {
console.error(err);
@ -71,11 +105,12 @@ class N1Launcher extends Application {
}
// Returns false or the window ID of the main window
static switchAndCheckForMain(client, windowId) {
// The `matcher` resolves to a boolean.
static switchAndCheckForMatch(client, windowId, matcher) {
return client.window(windowId).then(()=>{
return client.isExisting(".main-window-loaded").then((exists)=>{
if (exists) {return windowId} else {return false}
})
return matcher(client).then((isMatch) => {
if (isMatch) {return windowId} else {return false}
});
})
}
}

View file

@ -493,4 +493,4 @@ class Application
isSpec = true
devMode = true
safeMode ?= false
new NylasWindow({bootstrapScript, resourcePath, exitWhenDone, isSpec, devMode, specDirectory, specFilePattern, logFile, safeMode})
new NylasWindow({bootstrapScript, resourcePath, exitWhenDone, isSpec, devMode, specDirectory, specFilePattern, logFile, safeMode, showSpecsInWindow})