test(contenteditable): add in contenteditable list specs

This commit is contained in:
Evan Morikawa 2015-12-02 12:43:11 -08:00
parent 40e143e3f2
commit ced66902d5
6 changed files with 206 additions and 76 deletions

View file

@ -14,6 +14,7 @@ exports.safeExec = function(command, options, callback) {
// The default is 200KB.
options.maxBuffer = 1024 * 1024;
options.stdio = "inherit"
var child = childProcess.exec(command, options, function(error, stdout, stderr) {
if (error && !options.ignoreStderr)
process.exit(error.code || 1);
@ -31,9 +32,8 @@ exports.safeSpawn = function(command, args, options, callback) {
callback = options;
options = {};
}
options.stdio = "inherit"
var child = childProcess.spawn(command, args, options);
child.stderr.pipe(process.stderr);
child.stdout.pipe(process.stdout);
child.on('error', function(error) {
console.error('Command \'' + command + '\' failed: ' + error.message);
});

View file

@ -2,11 +2,38 @@
// argv[1] = jasmine
// argv[2] = JASMINE_CONFIG_PATH=./config.json
// argv[3] = NYLAS_ROOT_PATH=/path/to/nylas/root
var babelOptions = require('../static/babelrc.json');
require('babel-core/register')(babelOptions);
var chalk = require('chalk')
var util = require('util')
console.errorColor = function(err){
if (typeof err === "string") {
console.error(chalk.red(err));
} else {
console.error(chalk.red(util.inspect(err)));
}
}
console.inspect = function(val) {
console.log(util.inspect(val, true, depth=7, colorize=true));
}
jasmine.NYLAS_ROOT_PATH = process.argv[3].split("NYLAS_ROOT_PATH=")[1]
jasmine.UNIT_TEST_TIMEOUT = 120*1000;
jasmine.BOOT_TIMEOUT = 30*1000;
jasmine.DEFAULT_TIMEOUT_INTERVAL = 30*1000
Promise = require('bluebird')
Promise.config({
warnings: true,
longStackTraces: true,
cancellation: true
})
process.on("unhandledRejection", function(reason, promise) {
if (reason.stack) { console.errorColor(reason.stack); }
console.errorColor(promise);
});

View file

@ -1,18 +1,14 @@
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 = new ContenteditableTestHarness(this.app.client)
this.ce.init().finally(done);
});
@ -24,51 +20,120 @@ fdescribe('Contenteditable Integration Spec', function() {
}
});
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)
describe('Manipulating Lists', () => {
it("Creates ordered lists", (done)=> {
this.ce.test({
keys: ["1", ".", "Space"],
expectedHTML: "<ol><li></li></ol>",
expectedSelectionResolver: (dom) => {
return {node: dom.querySelectorAll('li')[0]} }
}).then(done).catch(done.fail)
});
it('Undoes ordered list creation with backspace', (done) => {
this.ce.test({
keys: ["1", ".", "Space", "Back space"],
expectedHTML: "1.&nbsp;<br>",
expectedSelectionResolver: (dom) => {
return {node: dom.childNodes[0], offset: 3} }
}).then(done).catch(done.fail)
});
it("Creates unordered lists with star", (done) => {
this.ce.test({
keys: ['*', 'Space'],
expectedHTML: "<ul><li></li></ul>",
expectedSelectionResolver: (dom) => {
return {node: dom.querySelectorAll("li")[0] } }
}).then(done).catch(done.fail)
});
it("Undoes unordered list creation with backspace", (done) => {
this.ce.test({
keys: ['*', 'Space', 'Back space'],
expectedHTML: "*&nbsp;<br>",
expectedSelectionResolver: (dom) => {
return {node: dom.childNodes[0], offset: 2} }
}).then(done).catch(done.fail)
});
it("Creates unordered lists with dash", (done) => {
this.ce.test({
keys: ['-', 'Space'],
expectedHTML: "<ul><li></li></ul>",
expectedSelectionResolver: (dom) => {
return {node: dom.querySelectorAll("li")[0] } }
}).then(done).catch(done.fail)
});
it("Undoes unordered list creation with backspace", (done) => {
this.ce.test({
keys: ['-', 'Space', 'Back space'],
expectedHTML: "-&nbsp;<br>",
expectedSelectionResolver: (dom) => {
return {node: dom.childNodes[0], offset: 2} }
}).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: "<span style=\"line-height: 1.4;\">a</span><br>",
// 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: "<span style=\"line-height: 1.4;\">a</span><br>",
// expectedSelectionResolver: (dom) => {
// return {node: dom.childNodes[0], offset: 1} }
// }).then(done).catch(done.fail)
// });
});
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)
});
describe('Ensuring popout composer window works', () => {
it("has main window visible", (done)=> {
this.app.client.isWindowVisible()
.then((result)=>{ expect(result).toBe(true) })
.then(done).catch(done.fail)
});
it("doesn't have the dev tools open", (done)=> {
this.app.client.isWindowDevToolsOpened()
.then((result)=>{ expect(result).toBe(false) })
.finally(done)
});
it("has main window focused", (done)=> {
this.app.client.isWindowFocused()
.then((result)=>{ expect(result).toBe(true) })
.then(done).catch(done.fail)
});
it("has width", (done)=> {
this.app.client.getWindowWidth()
.then((result)=>{ expect(result).toBeGreaterThan(0) })
.finally(done)
});
it("isn't minimized", (done)=> {
this.app.client.isWindowMinimized()
.then((result)=>{ expect(result).toBe(false) })
.then(done).catch(done.fail)
});
it("has height", (done)=> {
this.app.client.getWindowHeight()
.then((result)=>{ expect(result).toBeGreaterThan(0) })
.finally(done)
it("doesn't have the dev tools open", (done)=> {
this.app.client.isWindowDevToolsOpened()
.then((result)=>{ expect(result).toBe(false) })
.then(done).catch(done.fail)
});
it("has width", (done)=> {
this.app.client.getWindowWidth()
.then((result)=>{ expect(result).toBeGreaterThan(0) })
.then(done).catch(done.fail)
});
it("has height", (done)=> {
this.app.client.getWindowHeight()
.then((result)=>{ expect(result).toBeGreaterThan(0) })
.then(done).catch(done.fail)
});
});
});

View file

@ -1,43 +1,40 @@
import Promise from 'bluebird'
class ContenteditableTestHarness {
constructor(client, expect) {
this.expect = expect
constructor(client) {
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);
})
}
test({keys, expectedHTML, expectedSelectionResolver}) {
return this.client.keys(keys).then(()=>{
return this.expectHTML(expectedHTML)
}).then(()=>{
return this.expectSelection(expectedSelectionResolver)
})
}
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);
return this.client.execute(() => {
return document.querySelector(".contenteditable").innerHTML
}).then(({value})=>{
expect(value).toBe(expectedHTML)
})
}
expectSelection(callback) {
return this.client.execute(() => {
// Since `execute` fires parameters to Selenium via REST API, we can
// only pass strings. We serialize the callback so we can run it in
// the correct execution environment of the window instead of the
// Selenium wrapper.
return this.client.execute((callbackStr) => {
eval(`callback=${callbackStr}`);
ce = document.querySelector(".contenteditable")
expectSel = callback(ce)
@ -48,10 +45,51 @@ class ContenteditableTestHarness {
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)
return {
anchorNodeMatch: selection.anchorNode === anchorNode,
focusNodeMatch: selection.focusNode === focusNode,
anchorOffsetMatch: selection.anchorOffset === anchorOffset,
focusOffsetMatch: selection.focusOffset === focusOffset,
expectedAnchorNode: anchorNode.outerHTML,
expectedFocusNode: focusNode.outerHTML,
expectedAnchorOffset: anchorOffset,
expectedFocusOffset: focusOffset,
actualAnchorNode: selection.anchorNode.outerHTML,
actualFocusNode: selection.focusNode.outerHTML,
actualAnchorOffset: selection.anchorOffset,
actualFocusOffset: selection.focusOffset,
}
}, callback.toString()).then(({value}) => {
matchInfo = value
allMatched = true;
if (!matchInfo.anchorNodeMatch) {
console.errorColor("\nAnchor nodes don't match")
console.errorColor(`Expected: "${matchInfo.actualAnchorNode}" to be "${matchInfo.expectedAnchorNode}"`);
allMatched = false;
}
if (!matchInfo.focusNodeMatch) {
console.errorColor("\nFocus nodes don't match")
console.errorColor(`Expected: "${matchInfo.actualFocusNode}" to be "${matchInfo.expectedFocusNode}"`);
allMatched = false;
}
if (!matchInfo.anchorOffsetMatch) {
console.errorColor("\nAnchor offsets don't match")
console.errorColor(`Expected: ${matchInfo.actualAnchorOffset} to be ${matchInfo.expectedAnchorOffset}`);
allMatched = false;
}
if (!matchInfo.focusOffsetMatch) {
console.errorColor("\nFocus offsets don't match")
console.errorColor(`Expected: ${matchInfo.actualFocusOffset} to be ${matchInfo.expectedFocusOffset}`);
allMatched = false;
}
outMsgDescription = "matched. See discrepancies above"
if (allMatched) { outMsg = outMsgDescription
} else { outMsg = "Selection" }
// "Expected Selection to be matched. See discrepancies above"
expect(outMsg).toBe(outMsgDescription);
})
}
}

View file

@ -1,5 +1,4 @@
import path from 'path'
import Promise from 'bluebird'
import {Application} from 'spectron';
class N1Launcher extends Application {
@ -46,7 +45,7 @@ class N1Launcher extends Application {
return NylasEnv.getLoadSettings().windowType;
}).then(({value})=>{
if(value === "composer") {
return client.isWindowVisible()
return client.isExisting(".contenteditable")
} else {
return false
}

View file

@ -12,6 +12,7 @@
"bluebird": "^3.0.5",
"babel-core": "^5.8.21",
"jasmine": "^2.3.2",
"spectron": "^0.34.1"
"spectron": "^0.34.1",
"chalk": "^1.1"
}
}