Integration test: tape + spectron hello world
This commit is contained in:
@@ -66,7 +66,9 @@
|
|||||||
"plist": "^2.0.1",
|
"plist": "^2.0.1",
|
||||||
"rimraf": "^2.5.2",
|
"rimraf": "^2.5.2",
|
||||||
"run-series": "^1.1.4",
|
"run-series": "^1.1.4",
|
||||||
|
"spectron": "^3.3.0",
|
||||||
"standard": "*",
|
"standard": "*",
|
||||||
|
"tape": "^4.6.0",
|
||||||
"walk-sync": "^0.3.1"
|
"walk-sync": "^0.3.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -100,6 +102,7 @@
|
|||||||
"package": "node ./bin/package.js",
|
"package": "node ./bin/package.js",
|
||||||
"prepublish": "npm run build",
|
"prepublish": "npm run build",
|
||||||
"start": "npm run build && electron .",
|
"start": "npm run build && electron .",
|
||||||
|
"integration-test": "npm run build && node ./test",
|
||||||
"test": "standard && depcheck --ignores=babel-cli,nodemon,gh-release --ignore-dirs=build,dist && node ./bin/extra-lint.js",
|
"test": "standard && depcheck --ignores=babel-cli,nodemon,gh-release --ignore-dirs=build,dist && node ./bin/extra-lint.js",
|
||||||
"gh-release": "gh-release",
|
"gh-release": "gh-release",
|
||||||
"update-authors": "./bin/update-authors.sh",
|
"update-authors": "./bin/update-authors.sh",
|
||||||
|
|||||||
@@ -1,12 +1,22 @@
|
|||||||
const appConfig = require('application-config')('WebTorrent')
|
const appConfig = require('application-config')('WebTorrent')
|
||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
|
const electron = require('electron')
|
||||||
|
|
||||||
const APP_NAME = 'WebTorrent'
|
const APP_NAME = 'WebTorrent'
|
||||||
const APP_TEAM = 'WebTorrent, LLC'
|
const APP_TEAM = 'WebTorrent, LLC'
|
||||||
const APP_VERSION = require('../package.json').version
|
const APP_VERSION = require('../package.json').version
|
||||||
|
|
||||||
const PORTABLE_PATH = path.join(path.dirname(process.execPath), 'Portable Settings')
|
const IS_TEST = isTest()
|
||||||
|
const PORTABLE_PATH = IS_TEST
|
||||||
|
? path.join(__dirname, '../test/tempTestData')
|
||||||
|
: path.join(path.dirname(process.execPath), 'Portable Settings')
|
||||||
|
const IS_PORTABLE = isPortable()
|
||||||
|
const IS_PRODUCTION = isProduction()
|
||||||
|
|
||||||
|
console.log('Production: %s portable: %s test: %s',
|
||||||
|
IS_PRODUCTION, IS_PORTABLE, IS_TEST)
|
||||||
|
if (IS_PORTABLE) console.log('Portable path: %s', PORTABLE_PATH)
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
ANNOUNCEMENT_URL: 'https://webtorrent.io/desktop/announcement',
|
ANNOUNCEMENT_URL: 'https://webtorrent.io/desktop/announcement',
|
||||||
@@ -62,8 +72,9 @@ module.exports = {
|
|||||||
|
|
||||||
HOME_PAGE_URL: 'https://webtorrent.io',
|
HOME_PAGE_URL: 'https://webtorrent.io',
|
||||||
|
|
||||||
IS_PORTABLE: isPortable(),
|
IS_PORTABLE: IS_PORTABLE,
|
||||||
IS_PRODUCTION: isProduction(),
|
IS_PRODUCTION: IS_PRODUCTION,
|
||||||
|
IS_TEST: IS_TEST,
|
||||||
|
|
||||||
POSTER_PATH: path.join(getConfigPath(), 'Posters'),
|
POSTER_PATH: path.join(getConfigPath(), 'Posters'),
|
||||||
ROOT_PATH: path.join(__dirname, '..'),
|
ROOT_PATH: path.join(__dirname, '..'),
|
||||||
@@ -79,7 +90,7 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getConfigPath () {
|
function getConfigPath () {
|
||||||
if (isPortable()) {
|
if (IS_PORTABLE) {
|
||||||
return PORTABLE_PATH
|
return PORTABLE_PATH
|
||||||
} else {
|
} else {
|
||||||
return path.dirname(appConfig.filePath)
|
return path.dirname(appConfig.filePath)
|
||||||
@@ -89,22 +100,31 @@ function getConfigPath () {
|
|||||||
function getDefaultDownloadPath () {
|
function getDefaultDownloadPath () {
|
||||||
if (!process || !process.type) {
|
if (!process || !process.type) {
|
||||||
return ''
|
return ''
|
||||||
}
|
} else if (IS_PORTABLE) {
|
||||||
|
|
||||||
if (isPortable()) {
|
|
||||||
return path.join(getConfigPath(), 'Downloads')
|
return path.join(getConfigPath(), 'Downloads')
|
||||||
|
} else {
|
||||||
|
return getPath('downloads')
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const electron = require('electron')
|
function getPath (key) {
|
||||||
|
if (process.type === 'renderer') {
|
||||||
|
return electron.remote.app.getPath(key)
|
||||||
|
} else {
|
||||||
|
electron.app.getPath(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return process.type === 'renderer'
|
function isTest () {
|
||||||
? electron.remote.app.getPath('downloads')
|
return process.env.NODE_ENV === 'test'
|
||||||
: electron.app.getPath('downloads')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPortable () {
|
function isPortable () {
|
||||||
|
if (IS_TEST) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return process.platform === 'win32' && isProduction() && !!fs.statSync(PORTABLE_PATH)
|
return process.platform === 'win32' && IS_PRODUCTION && !!fs.statSync(PORTABLE_PATH)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
console.time('init')
|
console.time('init')
|
||||||
|
|
||||||
const electron = require('electron')
|
const electron = require('electron')
|
||||||
|
|
||||||
const app = electron.app
|
const app = electron.app
|
||||||
const ipcMain = electron.ipcMain
|
const ipcMain = electron.ipcMain
|
||||||
|
|
||||||
@@ -159,6 +158,10 @@ function processArgv (argv) {
|
|||||||
} else if (arg.startsWith('-psn')) {
|
} else if (arg.startsWith('-psn')) {
|
||||||
// Ignore Mac launchd "process serial number" argument
|
// Ignore Mac launchd "process serial number" argument
|
||||||
// Issue: https://github.com/feross/webtorrent-desktop/issues/214
|
// Issue: https://github.com/feross/webtorrent-desktop/issues/214
|
||||||
|
} else if (arg.startsWith('--')) {
|
||||||
|
// Ignore Spectron flags
|
||||||
|
} else if (arg === 'data:,') {
|
||||||
|
// Ignore weird Spectron argument
|
||||||
} else if (arg !== '.') {
|
} else if (arg !== '.') {
|
||||||
// Ignore '.' argument, which gets misinterpreted as a torrent id, when a
|
// Ignore '.' argument, which gets misinterpreted as a torrent id, when a
|
||||||
// development copy of WebTorrent is started while a production version is
|
// development copy of WebTorrent is started while a production version is
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ module.exports = class TorrentList extends React.Component {
|
|||||||
if (state.downloadPathStatus === 'missing') {
|
if (state.downloadPathStatus === 'missing') {
|
||||||
contents.push(
|
contents.push(
|
||||||
<div key='torrent-missing-path'>
|
<div key='torrent-missing-path'>
|
||||||
<p>Download path missing: {state.saved.prefs.downloadPath}</p>
|
<p id='torrent-error'>Download path missing: {state.saved.prefs.downloadPath}</p>
|
||||||
<p>Check that all drives are connected?</p>
|
<p>Check that all drives are connected?</p>
|
||||||
<p>Alternatively, choose a new download path
|
<p>Alternatively, choose a new download path
|
||||||
in <a href='#' onClick={dispatcher('preferences')}>Preferences</a>
|
in <a href='#' onClick={dispatcher('preferences')}>Preferences</a>
|
||||||
|
|||||||
41
test/index.js
Normal file
41
test/index.js
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
const test = require('tape')
|
||||||
|
const fs = require('fs-extra')
|
||||||
|
const path = require('path')
|
||||||
|
const setup = require('./setup')
|
||||||
|
|
||||||
|
console.log('Creating test dir: ' + setup.TEST_DATA_DIR)
|
||||||
|
const DOWNLOAD_DIR = path.join(setup.TEST_DATA_DIR, 'Downloads')
|
||||||
|
fs.mkdirpSync(DOWNLOAD_DIR)
|
||||||
|
|
||||||
|
test.onFinish(function () {
|
||||||
|
console.log('Removing test dir...')
|
||||||
|
fs.removeSync(setup.TEST_DATA_DIR)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('app runs', function (t) {
|
||||||
|
t.timeoutAfter(10e3)
|
||||||
|
const app = setup.createApp()
|
||||||
|
setup.waitForLoad(app, t)
|
||||||
|
.then(() => setup.wait())
|
||||||
|
.then(() => setup.screenshotCreateOrCompare(app, t, 'torrent-list-basic'))
|
||||||
|
.then(() => setup.endTest(app, t),
|
||||||
|
(err) => setup.endTest(app, t, err || 'error'))
|
||||||
|
})
|
||||||
|
|
||||||
|
test('show download path missing', function (t) {
|
||||||
|
fs.removeSync(DOWNLOAD_DIR)
|
||||||
|
|
||||||
|
t.timeoutAfter(10e3)
|
||||||
|
const app = setup.createApp()
|
||||||
|
setup.waitForLoad(app, t)
|
||||||
|
.then(() => app.client.getTitle())
|
||||||
|
.then((text) => console.log('Title ' + text))
|
||||||
|
.then(() => app.client.waitUntilTextExists('.torrent-list', 'Download path missing'))
|
||||||
|
.then((err) => t.notOk(err))
|
||||||
|
.then(() => app.client.click('a'))
|
||||||
|
.then(() => setup.wait())
|
||||||
|
.then(() => app.browserWindow.getTitle())
|
||||||
|
.then((windowTitle) => t.equal(windowTitle, 'Preferences'))
|
||||||
|
.then(() => setup.endTest(app, t),
|
||||||
|
(err) => setup.endTest(app, t, err || 'error'))
|
||||||
|
})
|
||||||
BIN
test/screenshots/darwin/torrent-list-basic.png
Normal file
BIN
test/screenshots/darwin/torrent-list-basic.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
69
test/setup.js
Normal file
69
test/setup.js
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
const path = require('path')
|
||||||
|
const Application = require('spectron').Application
|
||||||
|
const fs = require('fs-extra')
|
||||||
|
|
||||||
|
const TEST_DATA_DIR = path.join(__dirname, 'tempTestData')
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
TEST_DATA_DIR,
|
||||||
|
createApp,
|
||||||
|
endTest,
|
||||||
|
screenshotCreateOrCompare,
|
||||||
|
waitForLoad,
|
||||||
|
wait
|
||||||
|
}
|
||||||
|
|
||||||
|
// Runs WebTorrent Desktop.
|
||||||
|
// Returns a promise that resolves to a Spectron Application once the app has loaded.
|
||||||
|
// Takes a Tape test. Makes some basic assertions to verify that the app loaded correctly.
|
||||||
|
function createApp (t) {
|
||||||
|
return new Application({
|
||||||
|
path: path.join(__dirname, '..', 'node_modules', '.bin',
|
||||||
|
'electron' + (process.platform === 'win32' ? '.cmd' : '')),
|
||||||
|
args: [path.join(__dirname, '..')],
|
||||||
|
env: {NODE_ENV: 'test'}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Starts the app, waits for it to load, returns a promise
|
||||||
|
function waitForLoad (app, t) {
|
||||||
|
return app.start().then(function () {
|
||||||
|
return app.client.windowByIndex(1)
|
||||||
|
}).then(function () {
|
||||||
|
return app.client.waitUntilWindowLoaded()
|
||||||
|
}).then(function () {
|
||||||
|
return app.webContents.getTitle()
|
||||||
|
}).then(function (title) {
|
||||||
|
t.equal(title, 'WebTorrent Desktop', 'app title')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function wait (ms) {
|
||||||
|
if (ms === undefined) ms = 500 // Default: wait long enough for the UI to update
|
||||||
|
return new Promise(function (resolve, reject) {
|
||||||
|
setTimeout(resolve, ms)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function endTest (app, t, err) {
|
||||||
|
return app.stop().then(function () {
|
||||||
|
t.end(err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function screenshotCreateOrCompare (app, t, name) {
|
||||||
|
const ssPath = path.join(__dirname, 'screenshots', process.platform, name + '.png')
|
||||||
|
console.log('Capturing ' + ssPath)
|
||||||
|
fs.ensureFileSync(ssPath)
|
||||||
|
const ssBuf = fs.readFileSync(ssPath)
|
||||||
|
return app.browserWindow.capturePage().then(function (buffer) {
|
||||||
|
if (ssBuf.length === 0) {
|
||||||
|
console.log('Saving screenshot ' + ssPath)
|
||||||
|
fs.writeFileSync(ssPath, buffer)
|
||||||
|
} else if (Buffer.compare(buffer, ssBuf) !== 0) {
|
||||||
|
return Promise.reject('Screenshot didn\'t match: ' + ssPath)
|
||||||
|
} else {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user