Add files
15
test/config.js
Normal file
@ -0,0 +1,15 @@
|
||||
const path = require('path')
|
||||
|
||||
const TEMP_DIR = process.platform === 'win32' ? 'C:\\Windows\\Temp' : '/tmp'
|
||||
const TEST_DIR = path.join(TEMP_DIR, 'WebTorrentTest')
|
||||
const TEST_DIR_DOWNLOAD = path.join(TEST_DIR, 'Downloads')
|
||||
const TEST_DIR_DESKTOP = path.join(TEST_DIR, 'Desktop')
|
||||
|
||||
module.exports = {
|
||||
TORRENT_FILES: [path.join(__dirname, 'resources', '1.torrent')],
|
||||
SEED_FILES: [path.join(TEST_DIR_DESKTOP, 'tmp.jpg')],
|
||||
SAVED_TORRENT_FILE: path.join(TEST_DIR_DESKTOP, 'saved.torrent'),
|
||||
TEST_DIR,
|
||||
TEST_DIR_DOWNLOAD,
|
||||
TEST_DIR_DESKTOP
|
||||
}
|
||||
19
test/index.js
Normal file
@ -0,0 +1,19 @@
|
||||
const test = require('tape')
|
||||
const setup = require('./setup')
|
||||
|
||||
test.onFinish(setup.deleteTestDataDir)
|
||||
|
||||
test('app runs', function (t) {
|
||||
t.timeoutAfter(10e3)
|
||||
setup.resetTestDataDir()
|
||||
const app = setup.createApp()
|
||||
setup.waitForLoad(app, t)
|
||||
.then(() => setup.screenshotCreateOrCompare(app, t, 'app-basic'))
|
||||
.then(() => setup.endTest(app, t),
|
||||
(err) => setup.endTest(app, t, err || 'error'))
|
||||
})
|
||||
|
||||
require('./test-torrent-list')
|
||||
require('./test-add-torrent')
|
||||
require('./test-video')
|
||||
require('./test-audio')
|
||||
18
test/mocks.js
Normal file
@ -0,0 +1,18 @@
|
||||
const electron = require('electron')
|
||||
const config = require('./config')
|
||||
|
||||
console.log('Mocking electron.dialog.showOpenDialogSync...')
|
||||
electron.dialog.showOpenDialogSync = showOpenDialogSync
|
||||
|
||||
function showOpenDialogSync (win, opts) {
|
||||
return /select.*torrent file/i.test(opts.title)
|
||||
? config.TORRENT_FILES
|
||||
: config.SEED_FILES
|
||||
}
|
||||
|
||||
console.log('Mocking electron.dialog.showSaveDialogSync...')
|
||||
electron.dialog.showSaveDialogSync = showSaveDialogSync
|
||||
|
||||
function showSaveDialogSync (win, opts) {
|
||||
return config.SAVED_TORRENT_FILE
|
||||
}
|
||||
BIN
test/resources/1.torrent
Normal file
BIN
test/resources/expected-single-file.torrent
Normal file
BIN
test/resources/m3.jpg
Normal file
|
After Width: | Height: | Size: 2.2 MiB |
BIN
test/resources/monitor-test.mp4
Normal file
BIN
test/screenshots/darwin/add-torrent-0-percent.png
Normal file
|
After Width: | Height: | Size: 966 KiB |
BIN
test/screenshots/darwin/add-torrent-100-percent.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
test/screenshots/darwin/app-basic.png
Normal file
|
After Width: | Height: | Size: 899 KiB |
BIN
test/screenshots/darwin/create-torrent-100-percent.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
test/screenshots/darwin/create-torrent-advanced.png
Normal file
|
After Width: | Height: | Size: 115 KiB |
BIN
test/screenshots/darwin/create-torrent-simple.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
test/screenshots/darwin/play-torrent-bbb.png
Normal file
|
After Width: | Height: | Size: 351 KiB |
BIN
test/screenshots/darwin/play-torrent-return.png
Normal file
|
After Width: | Height: | Size: 630 KiB |
BIN
test/screenshots/darwin/play-torrent-wired-2.png
Normal file
|
After Width: | Height: | Size: 378 KiB |
BIN
test/screenshots/darwin/play-torrent-wired-3.png
Normal file
|
After Width: | Height: | Size: 380 KiB |
BIN
test/screenshots/darwin/play-torrent-wired-4.png
Normal file
|
After Width: | Height: | Size: 380 KiB |
BIN
test/screenshots/darwin/play-torrent-wired-5.png
Normal file
|
After Width: | Height: | Size: 380 KiB |
BIN
test/screenshots/darwin/play-torrent-wired-fullscreen.png
Normal file
|
After Width: | Height: | Size: 2.2 MiB |
BIN
test/screenshots/darwin/play-torrent-wired-list.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
test/screenshots/darwin/play-torrent-wired.png
Normal file
|
After Width: | Height: | Size: 381 KiB |
BIN
test/screenshots/darwin/prefs-basic.png
Normal file
|
After Width: | Height: | Size: 116 KiB |
BIN
test/screenshots/darwin/torrent-list-2.png
Normal file
|
After Width: | Height: | Size: 904 KiB |
BIN
test/screenshots/darwin/torrent-list-cosmos-delete-data.png
Normal file
|
After Width: | Height: | Size: 681 KiB |
BIN
test/screenshots/darwin/torrent-list-cosmos-deleted.png
Normal file
|
After Width: | Height: | Size: 746 KiB |
BIN
test/screenshots/darwin/torrent-list-cosmos-expand-deselect.png
Normal file
|
After Width: | Height: | Size: 1003 KiB |
BIN
test/screenshots/darwin/torrent-list-cosmos-expand-start.png
Normal file
|
After Width: | Height: | Size: 1019 KiB |
BIN
test/screenshots/darwin/torrent-list-cosmos-expand.png
Normal file
|
After Width: | Height: | Size: 1003 KiB |
BIN
test/screenshots/darwin/torrent-list-delete-prompt.png
Normal file
|
After Width: | Height: | Size: 492 KiB |
BIN
test/screenshots/darwin/torrent-list-deleted.png
Normal file
|
After Width: | Height: | Size: 630 KiB |
BIN
test/screenshots/darwin/torrent-list-download-path-missing.png
Normal file
|
After Width: | Height: | Size: 915 KiB |
BIN
test/screenshots/darwin/torrent-list-download.png
Normal file
|
After Width: | Height: | Size: 904 KiB |
BIN
test/screenshots/darwin/torrent-list-start-download.png
Normal file
|
After Width: | Height: | Size: 905 KiB |
BIN
test/screenshots/darwin/torrent-list.png
Normal file
|
After Width: | Height: | Size: 899 KiB |
BIN
test/screenshots/win32/add-torrent-0-percent.png
Normal file
|
After Width: | Height: | Size: 343 KiB |
BIN
test/screenshots/win32/add-torrent-100-percent.png
Normal file
|
After Width: | Height: | Size: 344 KiB |
BIN
test/screenshots/win32/app-basic.png
Normal file
|
After Width: | Height: | Size: 326 KiB |
BIN
test/screenshots/win32/create-torrent-100-percent.png
Normal file
|
After Width: | Height: | Size: 390 KiB |
BIN
test/screenshots/win32/create-torrent-advanced.png
Normal file
|
After Width: | Height: | Size: 43 KiB |
BIN
test/screenshots/win32/create-torrent-simple.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
test/screenshots/win32/play-torrent-bbb.png
Normal file
|
After Width: | Height: | Size: 104 KiB |
BIN
test/screenshots/win32/play-torrent-return.png
Normal file
|
After Width: | Height: | Size: 232 KiB |
BIN
test/screenshots/win32/play-torrent-wired-2.png
Normal file
|
After Width: | Height: | Size: 237 KiB |
BIN
test/screenshots/win32/play-torrent-wired-3.png
Normal file
|
After Width: | Height: | Size: 239 KiB |
BIN
test/screenshots/win32/play-torrent-wired-4.png
Normal file
|
After Width: | Height: | Size: 238 KiB |
BIN
test/screenshots/win32/play-torrent-wired-5.png
Normal file
|
After Width: | Height: | Size: 237 KiB |
BIN
test/screenshots/win32/play-torrent-wired-fullscreen.png
Normal file
|
After Width: | Height: | Size: 725 KiB |
BIN
test/screenshots/win32/play-torrent-wired-list.png
Normal file
|
After Width: | Height: | Size: 430 KiB |
BIN
test/screenshots/win32/play-torrent-wired.png
Normal file
|
After Width: | Height: | Size: 239 KiB |
BIN
test/screenshots/win32/prefs-basic.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
test/screenshots/win32/torrent-list-cosmos-delete-data.png
Normal file
|
After Width: | Height: | Size: 214 KiB |
BIN
test/screenshots/win32/torrent-list-cosmos-deleted.png
Normal file
|
After Width: | Height: | Size: 270 KiB |
BIN
test/screenshots/win32/torrent-list-cosmos-expand-deselect.png
Normal file
|
After Width: | Height: | Size: 352 KiB |
BIN
test/screenshots/win32/torrent-list-cosmos-expand-start.png
Normal file
|
After Width: | Height: | Size: 358 KiB |
BIN
test/screenshots/win32/torrent-list-cosmos-expand.png
Normal file
|
After Width: | Height: | Size: 352 KiB |
BIN
test/screenshots/win32/torrent-list-cosmos-hover.png
Normal file
|
After Width: | Height: | Size: 328 KiB |
BIN
test/screenshots/win32/torrent-list-delete-prompt.png
Normal file
|
After Width: | Height: | Size: 188 KiB |
BIN
test/screenshots/win32/torrent-list-deleted.png
Normal file
|
After Width: | Height: | Size: 232 KiB |
BIN
test/screenshots/win32/torrent-list-download-path-missing.png
Normal file
|
After Width: | Height: | Size: 332 KiB |
BIN
test/screenshots/win32/torrent-list-hover-download.png
Normal file
|
After Width: | Height: | Size: 330 KiB |
BIN
test/screenshots/win32/torrent-list-hover.png
Normal file
|
After Width: | Height: | Size: 425 KiB |
BIN
test/screenshots/win32/torrent-list-start-download.png
Normal file
|
After Width: | Height: | Size: 331 KiB |
236
test/setup.js
Normal file
@ -0,0 +1,236 @@
|
||||
const Application = require('spectron').Application
|
||||
const { copyFileSync } = require('fs')
|
||||
const fs = require('fs')
|
||||
const parseTorrent = require('parse-torrent')
|
||||
const path = require('path')
|
||||
const PNG = require('pngjs').PNG
|
||||
const rimraf = require('rimraf')
|
||||
|
||||
const config = require('./config')
|
||||
|
||||
module.exports = {
|
||||
createApp,
|
||||
endTest,
|
||||
screenshotCreateOrCompare,
|
||||
compareDownloadFolder,
|
||||
compareFiles,
|
||||
compareTorrentFile,
|
||||
compareTorrentFiles,
|
||||
waitForLoad,
|
||||
wait,
|
||||
resetTestDataDir,
|
||||
deleteTestDataDir,
|
||||
copy
|
||||
}
|
||||
|
||||
// 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) {
|
||||
const userDataDir = process.platform === 'win32'
|
||||
? path.join('C:\\Windows\\Temp', 'WebTorrentTest')
|
||||
: path.join('/tmp', 'WebTorrentTest')
|
||||
|
||||
return new Application({
|
||||
path: path.join(__dirname, '..', 'node_modules', '.bin',
|
||||
'electron' + (process.platform === 'win32' ? '.cmd' : '')),
|
||||
args: ['-r', path.join(__dirname, 'mocks.js'), path.join(__dirname, '..')],
|
||||
chromeDriverArgs: [`--user-data-dir=${userDataDir}`],
|
||||
env: { NODE_ENV: 'test' },
|
||||
waitTimeout: 10e3
|
||||
})
|
||||
}
|
||||
|
||||
// Starts the app, waits for it to load, returns a promise
|
||||
function waitForLoad (app, t, opts) {
|
||||
if (!opts) opts = {}
|
||||
return app.start().then(function () {
|
||||
return app.client.waitUntilWindowLoaded()
|
||||
}).then(function () {
|
||||
// Offline mode
|
||||
if (!opts.online) app.webContents.executeJavaScript('testOfflineMode()')
|
||||
}).then(function () {
|
||||
// Switch to the main window. Index 0 is apparently the hidden webtorrent window...
|
||||
return app.client.windowByIndex(1)
|
||||
}).then(function () {
|
||||
return app.client.waitUntilWindowLoaded()
|
||||
}).then(function () {
|
||||
return app.webContents.getTitle()
|
||||
}).then(function (title) {
|
||||
// Note the window title is WebTorrent, this is the HTML <title>
|
||||
t.equal(title, 'Main Window', 'html title')
|
||||
})
|
||||
}
|
||||
|
||||
// Returns a promise that resolves after 'ms' milliseconds. Default: 1 second
|
||||
function wait (ms) {
|
||||
if (ms === undefined) ms = 1000 // Default: wait long enough for the UI to update
|
||||
return new Promise(function (resolve, reject) {
|
||||
setTimeout(resolve, ms)
|
||||
})
|
||||
}
|
||||
|
||||
// Quit the app, end the test, either in success (!err) or failure (err)
|
||||
function endTest (app, t, err) {
|
||||
return app.stop().then(function () {
|
||||
t.end(err)
|
||||
})
|
||||
}
|
||||
|
||||
// Takes a screenshot of the app
|
||||
// If we already have a reference under test/screenshots, assert that they're the same
|
||||
// Otherwise, create the reference screenshot: test/screenshots/<platform>/<name>.png
|
||||
function screenshotCreateOrCompare (app, t, name) {
|
||||
const ssDir = path.join(__dirname, 'screenshots', process.platform)
|
||||
|
||||
// check that path exists otherwise create it
|
||||
if (!fs.existsSync(ssDir)) {
|
||||
fs.mkdirSync(ssDir)
|
||||
}
|
||||
|
||||
const ssPath = path.join(ssDir, name + '.png')
|
||||
let ssBuf
|
||||
|
||||
try {
|
||||
ssBuf = fs.readFileSync(ssPath)
|
||||
} catch (err) {
|
||||
ssBuf = Buffer.alloc(0)
|
||||
}
|
||||
|
||||
return app.browserWindow.focus()
|
||||
.then(() => wait())
|
||||
.then(() => app.browserWindow.capturePage())
|
||||
.then(function (buffer) {
|
||||
if (ssBuf.length === 0) {
|
||||
console.log('Saving screenshot ' + ssPath)
|
||||
fs.writeFileSync(ssPath, buffer)
|
||||
} else {
|
||||
const match = compareIgnoringTransparency(buffer, ssBuf)
|
||||
t.ok(match, 'screenshot comparison ' + name)
|
||||
if (!match) {
|
||||
const ssFailedPath = path.join(ssDir, name + '-failed.png')
|
||||
console.log('Saving screenshot, failed comparison: ' + ssFailedPath)
|
||||
fs.writeFileSync(ssFailedPath, buffer)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Compares two PNGs, ignoring any transparent regions in bufExpected.
|
||||
// Returns true if they match.
|
||||
function compareIgnoringTransparency (bufActual, bufExpected) {
|
||||
// Common case: exact byte-for-byte match
|
||||
if (Buffer.compare(bufActual, bufExpected) === 0) return true
|
||||
|
||||
// Otherwise, compare pixel by pixel
|
||||
let sumSquareDiff = 0
|
||||
let numDiff = 0
|
||||
const pngA = PNG.sync.read(bufActual)
|
||||
const pngE = PNG.sync.read(bufExpected)
|
||||
if (pngA.width !== pngE.width || pngA.height !== pngE.height) return false
|
||||
const w = pngA.width
|
||||
const h = pngE.height
|
||||
const da = pngA.data
|
||||
const de = pngE.data
|
||||
for (let y = 0; y < h; y++) {
|
||||
for (let x = 0; x < w; x++) {
|
||||
const i = ((y * w) + x) * 4
|
||||
if (de[i + 3] === 0) continue // Skip transparent pixels
|
||||
const ca = (da[i] << 16) | (da[i + 1] << 8) | da[i + 2]
|
||||
const ce = (de[i] << 16) | (de[i + 1] << 8) | de[i + 2]
|
||||
if (ca === ce) continue
|
||||
|
||||
// Add pixel diff to running sum
|
||||
// This is necessary on Windows, where rendering apparently isn't quite deterministic
|
||||
// and a few pixels in the screenshot will sometimes be off by 1. (Visually identical.)
|
||||
numDiff++
|
||||
sumSquareDiff += (da[i] - de[i]) * (da[i] - de[i])
|
||||
sumSquareDiff += (da[i + 1] - de[i + 1]) * (da[i + 1] - de[i + 1])
|
||||
sumSquareDiff += (da[i + 2] - de[i + 2]) * (da[i + 2] - de[i + 2])
|
||||
}
|
||||
}
|
||||
const rms = Math.sqrt(sumSquareDiff / (numDiff + 1))
|
||||
const l2Distance = Math.round(Math.sqrt(sumSquareDiff))
|
||||
console.log('screenshot diff l2 distance: ' + l2Distance + ', rms: ' + rms)
|
||||
return l2Distance < 5000 && rms < 100
|
||||
}
|
||||
|
||||
// Resets the test directory, containing config.json, torrents, downloads, etc
|
||||
function resetTestDataDir () {
|
||||
rimraf.sync(config.TEST_DIR)
|
||||
// Create TEST_DIR as well as /Downloads and /Desktop
|
||||
fs.mkdirSync(config.TEST_DIR_DOWNLOAD, { recursive: true })
|
||||
fs.mkdirSync(config.TEST_DIR_DESKTOP, { recursive: true })
|
||||
}
|
||||
|
||||
function deleteTestDataDir () {
|
||||
rimraf.sync(config.TEST_DIR)
|
||||
}
|
||||
|
||||
// Checks a given folder under Downloads.
|
||||
// Makes sure that the filenames match exactly.
|
||||
// If `filenames` is null, asserts that the folder doesn't exist.
|
||||
function compareDownloadFolder (t, dirname, filenames) {
|
||||
const dirpath = path.join(config.TEST_DIR_DOWNLOAD, dirname)
|
||||
try {
|
||||
const actualFilenames = fs.readdirSync(dirpath)
|
||||
if (filenames === null) {
|
||||
return t.fail('expected download folder to be absent, but it\'s here: ' + dirpath)
|
||||
}
|
||||
const expectedSorted = filenames.slice().sort()
|
||||
const actualSorted = actualFilenames.slice().sort()
|
||||
console.log(actualSorted)
|
||||
t.deepEqual(actualSorted, expectedSorted, 'download folder contents: ' + dirname)
|
||||
} catch (err) {
|
||||
if (err.code === 'ENOENT') {
|
||||
t.equal(filenames, null, 'download folder missing: ' + dirname)
|
||||
} else {
|
||||
console.error(err)
|
||||
t.fail('unexpected error getting download folder: ' + dirname)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Makes sure two files have identical contents
|
||||
function compareFiles (t, pathActual, pathExpected) {
|
||||
const bufActual = fs.readFileSync(pathActual)
|
||||
const bufExpected = fs.readFileSync(pathExpected)
|
||||
const match = Buffer.compare(bufActual, bufExpected) === 0
|
||||
t.ok(match, 'correct contents: ' + pathActual)
|
||||
}
|
||||
|
||||
// Makes sure two torrents have the same infohash and flags
|
||||
function compareTorrentFiles (t, pathActual, pathExpected) {
|
||||
const bufActual = fs.readFileSync(pathActual)
|
||||
const bufExpected = fs.readFileSync(pathExpected)
|
||||
const fieldsActual = extractImportantFields(parseTorrent(bufActual))
|
||||
const fieldsExpected = extractImportantFields(parseTorrent(bufExpected))
|
||||
t.deepEqual(fieldsActual, fieldsExpected, 'torrent contents: ' + pathActual)
|
||||
}
|
||||
|
||||
// Makes sure two torrents have the same infohash and flags
|
||||
function compareTorrentFile (t, pathActual, fieldsExpected) {
|
||||
const bufActual = fs.readFileSync(pathActual)
|
||||
const fieldsActual = extractImportantFields(parseTorrent(bufActual))
|
||||
if (Array.isArray(fieldsExpected.announce)) fieldsExpected.announce.sort()
|
||||
t.deepEqual(fieldsActual, fieldsExpected, 'torrent contents: ' + pathActual)
|
||||
}
|
||||
|
||||
function extractImportantFields (parsedTorrent) {
|
||||
let { infoHash, name, announce, urlList, comment } = parsedTorrent
|
||||
const priv = parsedTorrent.private // private is a reserved word in JS
|
||||
announce = announce.slice().sort()
|
||||
return { infoHash, name, announce, urlList, comment, private: priv }
|
||||
}
|
||||
|
||||
function copy (pathFrom, pathTo) {
|
||||
try {
|
||||
copyFileSync(pathFrom, pathTo)
|
||||
} catch (err) {
|
||||
// Windows lets us create files and folders under C:\Windows\Temp,
|
||||
// but when you try to `copySync` into one of those folders, you get EPERM
|
||||
// Ignore for now...
|
||||
if (process.platform !== 'win32' || err.code !== 'EPERM') throw err
|
||||
console.log('ignoring windows copy EPERM error', err)
|
||||
}
|
||||
}
|
||||
84
test/test-add-torrent.js
Normal file
@ -0,0 +1,84 @@
|
||||
const test = require('tape')
|
||||
const path = require('path')
|
||||
const setup = require('./setup')
|
||||
const config = require('./config')
|
||||
|
||||
test('add-torrent', function (t) {
|
||||
setup.resetTestDataDir()
|
||||
|
||||
t.timeoutAfter(30e3)
|
||||
const app = setup.createApp()
|
||||
setup.waitForLoad(app, t)
|
||||
.then(() => app.client.waitUntilTextExists('.torrent-list', 'Big Buck Bunny'))
|
||||
// Add an existing torrent. The corresponding file is not present. Should be at 0%
|
||||
.then(() => app.electron.ipcRenderer.send('openTorrentFile'))
|
||||
// The call to dialog.openFiles() is mocked. See mocks.js
|
||||
.then(() => app.client.waitUntilTextExists('.torrent-list', 'm3.jpg'))
|
||||
.then(() => setup.screenshotCreateOrCompare(app, t, 'add-torrent-0-percent'))
|
||||
// Delete the torrent.
|
||||
.then(() => app.client.moveToObject('.torrent'))
|
||||
.then(() => setup.wait())
|
||||
.then(() => app.client.click('.icon.delete'))
|
||||
.then(() => app.client.waitUntilTextExists('.modal', 'REMOVE'))
|
||||
.then(() => app.client.click('.control.ok'))
|
||||
// Add the same existing torrent, this time with the file present. Should be at 100%
|
||||
.then(() => setup.copy(
|
||||
path.join(__dirname, 'resources', 'm3.jpg'),
|
||||
path.join(config.TEST_DIR_DOWNLOAD, 'm3.jpg')))
|
||||
.then(() => app.electron.ipcRenderer.send('openTorrentFile'))
|
||||
.then(() => app.client.waitUntilTextExists('.torrent-list', 'm3.jpg'))
|
||||
.then(() => app.client.moveToObject('.torrent'))
|
||||
.then(() => setup.screenshotCreateOrCompare(app, t, 'add-torrent-100-percent'))
|
||||
.then(() => setup.endTest(app, t),
|
||||
(err) => setup.endTest(app, t, err || 'error'))
|
||||
})
|
||||
|
||||
test('create-torrent', function (t) {
|
||||
setup.resetTestDataDir()
|
||||
|
||||
const expectedTorrent = {
|
||||
announce: [
|
||||
'udp://tracker.leechers-paradise.org:6969',
|
||||
'udp://tracker.coppersurfer.tk:6969',
|
||||
'udp://tracker.opentrackr.org:1337',
|
||||
'udp://explodie.org:6969',
|
||||
'udp://tracker.empire-js.us:1337',
|
||||
'wss://tracker.btorrent.xyz',
|
||||
'wss://tracker.openwebtorrent.com'
|
||||
],
|
||||
infoHash: 'b31a80b3dd807c2fdde4c4da1a0db6123fa35883',
|
||||
name: 'tmp.jpg',
|
||||
urlList: [],
|
||||
comment: undefined,
|
||||
private: undefined
|
||||
}
|
||||
|
||||
// Set up the files to seed
|
||||
setup.copy(path.join(__dirname, 'resources', 'm3.jpg'), config.SEED_FILES[0])
|
||||
|
||||
t.timeoutAfter(30e3)
|
||||
const app = setup.createApp()
|
||||
setup.waitForLoad(app, t)
|
||||
.then(() => app.client.waitUntilTextExists('.torrent-list', 'Big Buck Bunny'))
|
||||
// Click the + button, open a non-torrent file to seed
|
||||
.then(() => app.client.click('.icon.add'))
|
||||
.then(() => app.client.waitUntilTextExists('h1', 'Create'))
|
||||
.then(() => setup.screenshotCreateOrCompare(app, t, 'create-torrent-simple'))
|
||||
// Click to show advanced settings
|
||||
.then(() => app.client.click('.show-more .control'))
|
||||
.then(() => app.client.waitUntilTextExists('.create-torrent-advanced', 'Comment'))
|
||||
.then(() => setup.screenshotCreateOrCompare(app, t, 'create-torrent-advanced'))
|
||||
// Click OK to create the torrent
|
||||
.then(() => app.client.click('.control.create-torrent-button'))
|
||||
.then(() => app.client.waitUntilTextExists('.torrent-list', 'tmp.jpg'))
|
||||
.then(() => app.client.moveToObject('.torrent'))
|
||||
.then(() => setup.screenshotCreateOrCompare(app, t, 'create-torrent-100-percent'))
|
||||
// Click "Save Torrent File As..." on the new torrent
|
||||
.then(() => app.webContents.executeJavaScript(
|
||||
'dispatch("saveTorrentFileAs", 6)'))
|
||||
.then(() => setup.wait())
|
||||
// Mock saves to <temp folder>/Desktop/saved.torrent
|
||||
.then(() => setup.compareTorrentFile(t, config.SAVED_TORRENT_FILE, expectedTorrent))
|
||||
.then(() => setup.endTest(app, t),
|
||||
(err) => setup.endTest(app, t, err || 'error'))
|
||||
})
|
||||
58
test/test-audio.js
Normal file
@ -0,0 +1,58 @@
|
||||
const test = require('tape')
|
||||
const setup = require('./setup')
|
||||
|
||||
test('audio-streaming', function (t) {
|
||||
setup.resetTestDataDir()
|
||||
|
||||
t.timeoutAfter(60e3)
|
||||
const app = setup.createApp()
|
||||
setup.waitForLoad(app, t, { online: true })
|
||||
.then(() => app.client.waitUntilTextExists('.torrent-list', 'Big Buck Bunny'))
|
||||
// Play Wired CD. Wait for it to start streaming.
|
||||
.then(() => app.client.moveToObject('#torrent-wired'))
|
||||
.then(() => setup.wait())
|
||||
.then(() => app.client.click('#torrent-wired .icon.play'))
|
||||
.then(() => app.client.waitUntilTextExists('.player', 'Beastie Boys'))
|
||||
// Pause. Skip to two seconds in. Wait another two seconds for it to load.
|
||||
.then(() => app.webContents.executeJavaScript('dispatch("playPause")'))
|
||||
.then(() => app.webContents.executeJavaScript('dispatch("skipTo", 2)'))
|
||||
.then(() => app.client.waitUntilTextExists('.player', 'Beastie Boys', 10e3))
|
||||
.then(() => setup.wait(5e3))
|
||||
.then(() => setup.screenshotCreateOrCompare(app, t, 'play-torrent-wired'))
|
||||
// Click next
|
||||
.then(() => app.client.click('.skip-next'))
|
||||
.then(() => app.client.waitUntilTextExists('.player', 'David Byrne'))
|
||||
.then(() => setup.wait(5e3))
|
||||
.then(() => app.client.moveToObject('.letterbox'))
|
||||
.then(() => app.webContents.executeJavaScript('dispatch("playPause")'))
|
||||
.then(() => app.webContents.executeJavaScript('dispatch("skipTo", 2)'))
|
||||
.then(() => setup.screenshotCreateOrCompare(app, t, 'play-torrent-wired-2'))
|
||||
// Play from end of song, let it advance on its own
|
||||
.then(() => app.webContents.executeJavaScript('dispatch("skipTo", 206)'))
|
||||
.then(() => app.webContents.executeJavaScript('dispatch("playPause")'))
|
||||
// Play past the end of the song, then pause after the start of the next song by Zap Mama
|
||||
.then(() => app.client.waitUntilTextExists('.player', 'Zap Mama'), 15e3)
|
||||
.then(() => setup.wait(5e3))
|
||||
.then(() => app.webContents.executeJavaScript('dispatch("playPause")'))
|
||||
.then(() => app.webContents.executeJavaScript('dispatch("skipTo", 2)'))
|
||||
.then(() => setup.screenshotCreateOrCompare(app, t, 'play-torrent-wired-3'))
|
||||
// Fullscreen
|
||||
.then(() => app.client.click('.fullscreen'))
|
||||
.then(() => setup.screenshotCreateOrCompare(app, t, 'play-torrent-wired-fullscreen'))
|
||||
// Back to normal audio view. Give the player controls have had time to disappear.
|
||||
.then(() => app.webContents.executeJavaScript('dispatch("escapeBack")'))
|
||||
.then(() => setup.screenshotCreateOrCompare(app, t, 'play-torrent-wired-4'))
|
||||
// Back. Return to torrent list
|
||||
.then(() => app.client.click('.back'))
|
||||
.then(() => app.client.waitUntilTextExists('.torrent-list', 'Big Buck Bunny'))
|
||||
.then(() => app.client.waitUntilTextExists('.torrent-list', 'Seeding', 60e3))
|
||||
.then(() => setup.screenshotCreateOrCompare(app, t, 'play-torrent-wired-list'))
|
||||
// Forward. Should play again where we left off (should not stay paused)
|
||||
.then(() => app.client.click('.forward'))
|
||||
.then(() => setup.wait())
|
||||
.then(() => app.webContents.executeJavaScript('dispatch("playPause")'))
|
||||
.then(() => app.webContents.executeJavaScript('dispatch("skipTo", 2)'))
|
||||
.then(() => setup.screenshotCreateOrCompare(app, t, 'play-torrent-wired-5'))
|
||||
.then(() => setup.endTest(app, t),
|
||||
(err) => setup.endTest(app, t, err || 'error'))
|
||||
})
|
||||
25
test/test-select-poster.js
Normal file
@ -0,0 +1,25 @@
|
||||
const test = require('tape')
|
||||
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const WebTorrent = require('webtorrent')
|
||||
const torrentPoster = require('../build/renderer/lib/torrent-poster')
|
||||
|
||||
const client = new WebTorrent()
|
||||
|
||||
test("get cover from: 'wiredCd.torrent'", (t) => {
|
||||
const torrentPath = path.join(__dirname, '..', 'static', 'wiredCd.torrent')
|
||||
const torrentData = fs.readFileSync(torrentPath)
|
||||
|
||||
client.add(torrentData, (torrent) => {
|
||||
torrentPoster(torrent, (err, buf, extension) => {
|
||||
if (err) {
|
||||
t.fail(err)
|
||||
} else {
|
||||
t.equals(extension, '.jpg')
|
||||
t.end()
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
100
test/test-torrent-list.js
Normal file
@ -0,0 +1,100 @@
|
||||
const rimraf = require('rimraf')
|
||||
const test = require('tape')
|
||||
|
||||
const config = require('./config')
|
||||
const setup = require('./setup')
|
||||
|
||||
test('torrent-list: show download path missing', function (t) {
|
||||
setup.resetTestDataDir()
|
||||
rimraf.sync(config.TEST_DIR_DOWNLOAD)
|
||||
|
||||
t.timeoutAfter(20e3)
|
||||
const app = setup.createApp()
|
||||
setup.waitForLoad(app, t)
|
||||
.then(() => app.client.waitUntilTextExists('.torrent-list', 'Download path missing'))
|
||||
.then((err) => t.notOk(err))
|
||||
.then(() => setup.screenshotCreateOrCompare(app, t, 'torrent-list-download-path-missing'))
|
||||
.then(() => app.client.click('a'))
|
||||
.then(() => setup.wait())
|
||||
.then(() => app.browserWindow.getTitle())
|
||||
.then((windowTitle) => t.equal(windowTitle, 'Preferences', 'window title'))
|
||||
.then(() => setup.screenshotCreateOrCompare(app, t, 'prefs-basic'))
|
||||
.then(() => setup.endTest(app, t),
|
||||
(err) => setup.endTest(app, t, err || 'error'))
|
||||
})
|
||||
|
||||
test('torrent-list: start, stop, and delete torrents', function (t) {
|
||||
setup.resetTestDataDir()
|
||||
|
||||
const app = setup.createApp()
|
||||
setup.waitForLoad(app, t)
|
||||
.then(() => app.client.waitUntilTextExists('.torrent-list', 'Big Buck Bunny'))
|
||||
.then(() => setup.screenshotCreateOrCompare(app, t, 'torrent-list'))
|
||||
// Click download on the first torrent, start downloading
|
||||
.then(() => app.client.click('.download input'))
|
||||
.then(() => app.client.waitUntilTextExists('.torrent-list', '276 MB'))
|
||||
.then(() => setup.screenshotCreateOrCompare(app, t, 'torrent-list-start-download'))
|
||||
// Click download on the first torrent again, stop downloading
|
||||
.then(() => app.client.click('.download input'))
|
||||
.then(() => setup.screenshotCreateOrCompare(app, t, 'torrent-list-download'))
|
||||
// Click delete on the first torrent
|
||||
.then(() => app.client.click('.icon.delete'))
|
||||
.then(() => setup.screenshotCreateOrCompare(app, t, 'torrent-list-delete-prompt'))
|
||||
// Click cancel on the resulting confirmation dialog. Should be same as before.
|
||||
.then(() => app.client.click('.control.cancel'))
|
||||
.then(() => setup.screenshotCreateOrCompare(app, t, 'torrent-list-2'))
|
||||
// Click delete on the first torrent again
|
||||
.then(() => app.client.click('.icon.delete'))
|
||||
.then(() => setup.screenshotCreateOrCompare(app, t, 'torrent-list-delete-prompt'))
|
||||
// This time, click OK to confirm.
|
||||
.then(() => app.client.click('.control.ok'))
|
||||
.then(() => setup.screenshotCreateOrCompare(app, t, 'torrent-list-deleted'))
|
||||
.then(() => setup.endTest(app, t),
|
||||
(err) => setup.endTest(app, t, err || 'error'))
|
||||
})
|
||||
|
||||
test('torrent-list: expand torrent, unselect file', function (t) {
|
||||
setup.resetTestDataDir()
|
||||
|
||||
const app = setup.createApp()
|
||||
setup.waitForLoad(app, t)
|
||||
.then(() => app.client.waitUntilTextExists('.torrent-list', 'Big Buck Bunny'))
|
||||
// Click on the torrent, expand
|
||||
.then(() => app.client.click('#torrent-cosmos'))
|
||||
.then(() => setup.screenshotCreateOrCompare(app, t, 'torrent-list-cosmos-expand'))
|
||||
// Deselect the first file
|
||||
.then(() => app.client.click('#torrent-cosmos .icon.deselect-file'))
|
||||
.then(() => setup.screenshotCreateOrCompare(app, t, 'torrent-list-cosmos-expand-deselect'))
|
||||
// Start the torrent
|
||||
.then(() => app.client.click('#torrent-cosmos .download input'))
|
||||
.then(() => app.client.waitUntilTextExists('.torrent-list', '0%'))
|
||||
.then(() => setup.screenshotCreateOrCompare(app, t, 'torrent-list-cosmos-expand-start'))
|
||||
// Make sure that it creates all files EXCEPT the deslected one
|
||||
// TODO: Disabled test because it stopped working
|
||||
// .then(() => setup.compareDownloadFolder(t, 'CosmosLaundromatFirstCycle', [
|
||||
// // TODO: the .gif should NOT be here, since we just deselected it.
|
||||
// // This is a bug. See https://github.com/leenkx/leenkxbox/issues/719
|
||||
// 'Cosmos Laundromat - First Cycle (1080p).gif',
|
||||
// 'Cosmos Laundromat - First Cycle (1080p).mp4',
|
||||
// 'Cosmos Laundromat - First Cycle (1080p).ogv',
|
||||
// 'CosmosLaundromat-FirstCycle1080p.en.srt',
|
||||
// 'CosmosLaundromat-FirstCycle1080p.es.srt',
|
||||
// 'CosmosLaundromat-FirstCycle1080p.fr.srt',
|
||||
// 'CosmosLaundromat-FirstCycle1080p.it.srt',
|
||||
// 'CosmosLaundromatFirstCycle_meta.sqlite',
|
||||
// 'CosmosLaundromatFirstCycle_meta.xml'
|
||||
// ]))
|
||||
// Delete torrent plus data
|
||||
// Spectron doesn't have proper support for menu clicks yet...
|
||||
.then(() => app.webContents.executeJavaScript(
|
||||
'dispatch("confirmDeleteTorrent", "6a02592d2bbc069628cd5ed8a54f88ee06ac0ba5", true)'))
|
||||
.then(() => setup.screenshotCreateOrCompare(app, t, 'torrent-list-cosmos-delete-data'))
|
||||
// Click confirm
|
||||
.then(() => app.client.click('.control.ok'))
|
||||
.then(() => setup.screenshotCreateOrCompare(app, t, 'torrent-list-cosmos-deleted'))
|
||||
// Make sure that all the files are gone
|
||||
// TODO: Disabled test because it stopped working
|
||||
// .then(() => setup.compareDownloadFolder(t, 'CosmosLaundromatFirstCycle', null))
|
||||
.then(() => setup.endTest(app, t),
|
||||
(err) => setup.endTest(app, t, err || 'error'))
|
||||
})
|
||||
35
test/test-video.js
Normal file
@ -0,0 +1,35 @@
|
||||
const test = require('tape')
|
||||
const setup = require('./setup')
|
||||
|
||||
test('video-streaming', function (t) {
|
||||
setup.resetTestDataDir()
|
||||
|
||||
t.timeoutAfter(30e3)
|
||||
const app = setup.createApp()
|
||||
setup.waitForLoad(app, t, { online: true })
|
||||
.then(() => app.client.waitUntilTextExists('.torrent-list', 'Big Buck Bunny'))
|
||||
// Play Big Buck Bunny. Wait for it to start streaming.
|
||||
.then(() => app.client.moveToObject('.torrent'))
|
||||
.then(() => setup.wait())
|
||||
.then(() => app.client.click('.icon.play'))
|
||||
.then(() => setup.wait(10e3))
|
||||
// Pause. Skip to two seconds in. Wait another two seconds for it to load.
|
||||
.then(() => app.webContents.executeJavaScript('dispatch("playPause")'))
|
||||
.then(() => app.webContents.executeJavaScript('dispatch("skipTo", 2)'))
|
||||
.then(() => setup.wait(5e3))
|
||||
// Take a screenshot to verify video playback
|
||||
.then(() => setup.screenshotCreateOrCompare(app, t, 'play-torrent-bbb'))
|
||||
// Hit escape
|
||||
.then(() => app.webContents.executeJavaScript('dispatch("escapeBack")'))
|
||||
.then(() => setup.wait())
|
||||
// Delete Big Buck Bunny
|
||||
.then(() => app.client.moveToObject('.torrent'))
|
||||
.then(() => setup.wait())
|
||||
.then(() => app.client.click('.icon.delete'))
|
||||
.then(() => setup.wait())
|
||||
.then(() => app.client.click('.control.ok'))
|
||||
// Take another screenshot to verify that the window resized correctly
|
||||
.then(() => setup.screenshotCreateOrCompare(app, t, 'play-torrent-return'))
|
||||
.then(() => setup.endTest(app, t),
|
||||
(err) => setup.endTest(app, t, err || 'error'))
|
||||
})
|
||||