Skip to content
This repository was archived by the owner on Aug 19, 2019. It is now read-only.

Better testing #56

Merged
merged 8 commits into from
Feb 23, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ language: node_js
node_js:
- '7'

script: ./test/travis-build.sh
script: ./test/runtests.sh

cache:
yarn: true
Expand Down
30 changes: 30 additions & 0 deletions functest/e2e.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const assert = require('assert');
const {setDialogAnswer, setMessageBoxAnswer} = require('./mocks.js');
const fs = require('fs-extra');
const Path = require('path');
const {waitUntilEqual} = require('./util.js');
const Mocha = require('mocha');
const {app} = require('../src/main.js');

const Tmp = require('tmp');
Tmp.setGracefulCleanup();

app.on('ready', function() {
let mocha = new Mocha();
let testDir = 'functest';
fs.readdirSync(testDir).filter(function(file){
// Only keep the .js files
return file.substr(-3) === '.js' && Path.basename(file).startsWith('test_');
}).forEach(function(file){
mocha.addFile(
Path.join(testDir, file)
);
});

mocha.run(function(failures){
process.on('exit', function () {
process.exit(failures && 1); // exit with non-zero status if there were failures
});
process.exit(0);
});
})
23 changes: 23 additions & 0 deletions functest/mocks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
var {dialog} = require('electron');

let dialog_path = [];
let message_choice = 0;

dialog.showOpenDialog = (options, cb) => {
cb(dialog_path);
}
dialog.showSaveDialog = (options, cb) => {
cb(dialog_path);
}
dialog.showMessageBox = (options) => {
return message_choice;
}

function setDialogAnswer(answer) {
dialog_path = answer;
}
function setMessageBoxAnswer(answer) {
message_choice = answer;
}

module.exports = {setDialogAnswer, setMessageBoxAnswer};
284 changes: 284 additions & 0 deletions functest/test_e2e.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,284 @@
var assert = require('assert');
// var chai = require('chai');
// var chaiAsPromised = require('chai-as-promised');
const {mock, setDialogAnswer, setMessageBoxAnswer} = require('./mocks.js');
var fs = require('fs-extra');
var Path = require('path');
const {app, openPath, saveFocusedDoc, saveAsFocusedDoc, closeFocusedDoc, reloadFocusedDoc} = require('../src/main.js');
const {waitUntil, waitUntilEqual} = require('./util.js');
const {webContents, BrowserWindow} = require('electron');
const AdmZip = require('adm-zip');

const Tmp = require('tmp');
Tmp.setGracefulCleanup();

const _ = require('lodash');

function _wrapFunction(func) {
if (_.isFunction(func)) {
return `(function() {
try {
return (${func.toString()})();
} catch(err) {
return {executeJavaScriptError:err.toString()};
}
})()`;
}
return func;
}

function executeJavaScript(web, func) {
let code = _wrapFunction(func)
return web.executeJavaScript(code, /* because of issue 8743 */()=>{})
.then(result => {
if (result && result.executeJavaScriptError) {
throw new Error(result.executeJavaScriptError);
}
return result;
})
.catch(err => {
console.log('error', err);
})
}

function readFromZip(zipfile, path) {
let zip = new AdmZip(zipfile);
return zip.readFile(path);
}

function openDocument(path) {
openPath(path);
return waitUntil(function() {
return BrowserWindow.getAllWindows().length == 1;
})
.then(() => {
return waitUntil(function() {
return webContents.getAllWebContents().length == 2;
})
})
.then(() => {
return waitUntil(function() {
return _.filter(webContents.getAllWebContents(), wc => {
return wc.isLoading();
}).length === 0;
})
})
.then(() => {
let webview;
let container;
_.each(webContents.getAllWebContents(), wc => {
if (wc.getURL().startsWith('lhtml://')) {
webview = wc;
} else {
container = wc;
}
})
return {
webview: webview,
container: container,
}
})
}

function reloadDocument() {
reloadFocusedDoc()
return waitUntil(function() {
return _.filter(webContents.getAllWebContents(), wc => {
return wc.isLoading();
}).length === 0;
})
}

assert.contains = function(haystack, needle) {
let assertion;
if (haystack === null || needle === null) {
assertion = false;
} else {
assertion = haystack.indexOf(needle) !== -1
}
return assert.ok(assertion, `Expected to find\n-->${needle}<--\ninside\n-->${haystack}<--`)
}
assert.doesNotContain = function(haystack, needle) {
let assertion;
if (haystack === null || needle === null) {
assertion = false;
} else {
assertion = haystack.indexOf(needle) === -1
}
return assert.ok(assertion, `Expected not to find\n-->${needle}<--\ninside\n-->${haystack}<--`);
}

describe('app launch', function() {
this.timeout(10000);

beforeEach(() => {
});
afterEach(() => {
return closeFocusedDoc();
});

//----------------------------------------------------------------------
// saving/loading
//----------------------------------------------------------------------
describe('saving', function() {
let workdir;
beforeEach(() => {
workdir = Tmp.dirSync({unsafeCleanup: true}).name;
console.log('working in', workdir);
});

describe('from LHTML dir,', function() {
let src_dir;
let webview;
let container;

beforeEach(() => {
src_dir = Path.join(workdir, 'src');
fs.ensureDirSync(src_dir);
fs.writeFileSync(Path.join(src_dir, 'index.html'),
'<html><body><input id="theinput"></body></html>');
return openDocument(src_dir)
.then(result => {
webview = result.webview;
container = result.container;
})
})

it('"Save" should overwrite dir', () => {
return executeJavaScript(webview, function() {
return document.getElementById('theinput').setAttribute('value', 'jimbo');
})
.then(() => {
return saveFocusedDoc()
})
.then(() => {
assert.contains(fs.readFileSync(Path.join(src_dir, 'index.html')),
'jimbo');
})
.then(() => {
return reloadDocument()
})
.then(() => {
return executeJavaScript(webview, function() {
return document.getElementById('theinput').getAttribute('value')
})
})
.then(value => {
assert.equal(value, 'jimbo');
})
});

it('"Save As" should create a new file', () => {
let dst_file = Path.join(workdir, 'dst.lhtml');
return executeJavaScript(webview, function() {
return document.getElementById('theinput').setAttribute('value', 'garbage');
})
.then(() => {
setDialogAnswer(dst_file)
return saveAsFocusedDoc()
})
.then(() => {
// Should not have overwritten original
assert.doesNotContain(fs.readFileSync(Path.join(src_dir, 'index.html')),
'garbage');
})
.then(() => {
// Should have written new file
assert.contains(readFromZip(dst_file, './index.html'), 'garbage');
})
.then(() => {
return reloadDocument()
})
.then(() => {
// Should be using the new file
return executeJavaScript(webview, function() {
return document.getElementById('theinput').getAttribute('value')
})
})
.then(value => {
assert.equal(value, 'garbage');
})
});
});

describe('from LHTML file', function() {
let src_file;
let src_dir;
let webview;
let container;

beforeEach(() => {
src_file = Path.join(workdir, 'src.lhtml');
src_dir = Path.join(workdir, 'src');
let zip = new AdmZip();
zip.addFile('./index.html', '<html><body><input id="theinput"></body></html>');
zip.writeZip(src_file);

return openDocument(src_file)
.then(result => {
webview = result.webview;
container = result.container;
})
})

it('"Save" should overwrite file', () => {
return executeJavaScript(webview, function() {
return document.getElementById('theinput').setAttribute('value', 'jimbo');
})
.then(() => {
return saveFocusedDoc()
})
.then(() => {
assert.contains(readFromZip(src_file, './index.html'), 'jimbo');
})
.then(() => {
return reloadDocument()
})
.then(() => {
return executeJavaScript(webview, function() {
return document.getElementById('theinput').getAttribute('value')
})
})
.then(value => {
assert.equal(value, 'jimbo');
})
});

it('"Save As" should create a new file', () => {
let dst_file = Path.join(workdir, 'dst.lhtml');
return executeJavaScript(webview, function() {
return document.getElementById('theinput').setAttribute('value', 'garbage');
})
.then(() => {
setDialogAnswer(dst_file)
return saveAsFocusedDoc()
})
.then(() => {
// Should not have overwritten original
assert.doesNotContain(readFromZip(src_file, './index.html'), 'garbage')
})
.then(() => {
// Should have written new file with data in it
assert.contains(readFromZip(dst_file, './index.html'), 'garbage')
})
.then(() => {
return reloadDocument()
})
.then(() => {
// Should be using the new file
return executeJavaScript(webview, function() {
return document.getElementById('theinput').getAttribute('value')
})
})
.then(value => {
assert.equal(value, 'garbage');
})
});
});
})
})





File renamed without changes.
9 changes: 4 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"description": "LHTML Viewer",
"author": "Matt Haggard <[email protected]>",
"scripts": {
"test": "mocha",
"test": "test/runtests.sh",
"pack": "build --dir",
"dist": "build",
"postinstall": "install-app-deps"
Expand All @@ -16,9 +16,7 @@
"electron-builder": "^13.6.0",
"electron-packager": "^8.5.0",
"esdoc": "^0.5.2",
"http-server": "^0.9.0",
"mocha": "^3.2.0",
"spectron": "^3.4.1"
"mocha": "^3.2.0"
},
"dependencies": {
"adm-zip": "^0.4.7",
Expand Down Expand Up @@ -46,7 +44,8 @@
"!samples${/*}",
"!demos${/*}",
"!doc${/*}",
"!test${/*}"
"!test${/*}",
"!functest${/*}"
],
"fileAssociations": [
{
Expand Down
Loading