123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- /* eslint-disable compat/compat */
- /* global window, capabilities */
- const path = require('path')
- const { spawn } = require('child_process')
- const { promisify } = require('util')
- // This function must be valid ES5, because it is run in the browser
- // and IE10/IE11 do not support new syntax features
- function selectFakeFile (uppyID, name, type, b64) {
- if (!b64) b64 = 'PHN2ZyB2aWV3Qm94PSIwIDAgMTIwIDEyMCI+CiAgPGNpcmNsZSBjeD0iNjAiIGN5PSI2MCIgcj0iNTAiLz4KPC9zdmc+Cg=='
- if (!type) type = 'image/svg+xml'
- // https://stackoverflow.com/questions/16245767/creating-a-blob-from-a-base64-string-in-javascript
- function base64toBlob (base64Data, contentType) {
- contentType = contentType || ''
- var sliceSize = 1024
- var byteCharacters = atob(base64Data)
- var bytesLength = byteCharacters.length
- var slicesCount = Math.ceil(bytesLength / sliceSize)
- var byteArrays = new Array(slicesCount)
- for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
- var begin = sliceIndex * sliceSize
- var end = Math.min(begin + sliceSize, bytesLength)
- var bytes = new Array(end - begin)
- for (var offset = begin, i = 0; offset < end; ++i, ++offset) {
- bytes[i] = byteCharacters[offset].charCodeAt(0)
- }
- byteArrays[sliceIndex] = new Uint8Array(bytes)
- }
- return new Blob(byteArrays, { type: contentType })
- }
- var blob = base64toBlob(b64, type)
- window[uppyID].addFile({
- source: 'test',
- name: name || 'test-file',
- type: blob.type,
- data: blob,
- })
- }
- function ensureInputVisible (selector) {
- var input = document.querySelector(selector)
- input.style = 'width: auto; height: auto; opacity: 1; z-index: 199'
- input.removeAttribute('hidden')
- input.removeAttribute('aria-hidden')
- input.removeAttribute('tabindex')
- }
- function supportsChooseFile () {
- // no remote file uploads right now...
- if (process.env.CI) return false
- // Webdriver for Safari and Edge doesn’t support .chooseFile
- return capabilities.browserName !== 'Safari'
- && capabilities.browserName !== 'MicrosoftEdge'
- && capabilities.platformName !== 'Android'
- }
- function prematureExit () {
- throw new Error('Companion exited early')
- }
- class CompanionService {
- onPrepare () {
- this.companion = spawn('node', [
- path.join(__dirname, '../../packages/@uppy/companion/lib/standalone/start-server'),
- ], {
- stdio: 'pipe',
- env: {
- ...process.env,
- COMPANION_DATADIR: path.join(__dirname, '../../output'),
- COMPANION_DOMAIN: 'localhost:3030',
- COMPANION_PROTOCOL: 'http',
- COMPANION_PORT: 3030,
- COMPANION_SECRET: process.env.TEST_COMPANION_SECRET,
- COMPANION_DROPBOX_KEY: process.env.TEST_COMPANION_DROPBOX_KEY,
- COMPANION_DROPBOX_SECRET: process.env.TEST_COMPANION_DROPBOX_SECRET,
- COMPANION_GOOGLE_KEY: process.env.TEST_COMPANION_GOOGLE_KEY,
- COMPANION_GOOGLE_SECRET: process.env.TEST_COMPANION_GOOGLE_SECRET,
- },
- })
- return new Promise((resolve, reject) => {
- this.companion.on('error', reject)
- this.companion.stdout.on('data', (chunk) => {
- if (`${chunk}`.includes('Listening on')) {
- resolve()
- }
- })
- this.companion.on('error', console.error)
- this.companion.stderr.pipe(process.stderr)
- this.companion.on('exit', prematureExit)
- })
- }
- onComplete () {
- return new Promise((resolve) => {
- this.companion.removeListener('exit', prematureExit)
- this.companion.on('exit', () => resolve())
- this.companion.kill('SIGINT')
- })
- }
- }
- const express = require('express')
- class StaticServerService {
- constructor ({ folders, staticServerPort = 4567 }) {
- this.folders = folders
- this.port = staticServerPort
- }
- async onPrepare () {
- if (!this.folders) return
- this.app = express()
- for (const desc of this.folders) {
- this.app.use(desc.mount, express.static(desc.path))
- }
- const listen = promisify(this.app.listen.bind(this.app))
- this.server = await listen(this.port)
- }
- async onComplete () {
- if (this.server) {
- const close = promisify(this.server.close.bind(this.server))
- await close()
- }
- this.app = null
- }
- }
- const tus = require('tus-node-server')
- const os = require('os')
- const rimraf = promisify(require('rimraf'))
- const { randomBytes } = require('crypto')
- const http = require('http')
- const httpProxy = require('http-proxy')
- const brake = require('brake')
- class TusService {
- constructor ({ tusServerPort = 1080 }) {
- this.port = tusServerPort
- this.path = path.join(os.tmpdir(), `uppy-e2e-tus-node-server-${randomBytes(6).toString('hex')}`)
- }
- async onPrepare () {
- this.tusServer = new tus.Server()
- this.tusServer.datastore = new tus.FileStore({
- path: '/files',
- directory: this.path,
- })
- const proxy = httpProxy.createProxyServer()
- this.slowServer = http.createServer((req, res) => {
- proxy.web(req, res, {
- target: 'http://localhost:1080',
- // 200 kbps max upload, checking the rate limit every 20ms
- buffer: req.pipe(brake({
- period: 20,
- rate: 200 * 1024 / 50,
- })),
- }, (err) => { // eslint-disable-line handle-callback-err
- // ignore, typically a cancelled request
- })
- })
- const listen = promisify(this.tusServer.listen.bind(this.tusServer))
- this.server = await listen({ host: '0.0.0.0', port: this.port })
- const listen2 = promisify(this.slowServer.listen.bind(this.slowServer))
- await listen2(this.port + 1)
- }
- async onComplete () {
- if (this.slowServer) {
- const close = promisify(this.slowServer.close.bind(this.slowServer))
- await close()
- }
- if (this.server) {
- const close = promisify(this.server.close.bind(this.server))
- await close()
- }
- await rimraf(this.path)
- this.slowServer = null
- this.tusServer = null
- }
- }
- module.exports = {
- selectFakeFile,
- ensureInputVisible,
- supportsChooseFile,
- CompanionService,
- StaticServerService,
- TusService,
- }
|