mirror of
https://github.com/cypress-io/cypress.git
synced 2026-02-21 14:41:00 -06:00
* initial commit, a kinda working prototype * Ready to test in CI * "SyntaxError: Cannot use import statement outside a module" I blame VS code for always inserting the wrong dependency * try using built js instead of the ts file * typescript fixes? * get version correctly, don't use optional chaining in child process. * trying this, idk * try running telemetry for driver-integration-tests-chrome * fix missing spans, add more attributes for some spans * fix missing spans and add suite spans * types * Remove un-used require * remove spans for describe blocks in favor of the full title for tests * migrate to sync resource discovery, start new custom exporters for spans * encrypted * localhost * don't do things on child process * latest changes * update server start span time / add v8 snapshot span & update command span names * prepare for sync * don't send blank key * make telemetry work again for sending directly to honeycomb * web-socket exporter * Add in IPC exporter and message the child process before disconnecting * Use the cloud api by default * move cloud span exporter into telemetry package * shutdown fixes * fix enabled * improve types * run in ci * yml is the worst * type! * add spans for timing insights for visible areas of improvement * type errors * lets try sending data to staging * types * types again * remove problematic attributes * clean up exporters * i like this better even though it doesn't seem to matter much * some self review cleanup * Update comment * add debug messages * mocha tests * actually exit with the right code... oops * simple mistake... have to look into how to fix with ts... * try this i guess * don't return undefined * read me diagram * color? * no rect * moar diagram * docs! * formatting * build more binaries * Supposedly fix cypress in cypress test failures * test 'fixes' * try this instead * do not transpile cypress packages dir * lets try escaping our regex string * Add some diagnostics to help test the built binary.... * try a more complex solution * fix tests probably * just ignore the specific file * fix unit tests * cr updates * Apply suggestions from code review Co-authored-by: Matt Schile <mschile@cypress.io> Co-authored-by: Bill Glesias <bglesias@gmail.com> * Pr updates * don't change the command queue * move encoding and decoding telemetry context for ipc to the telemetry package * build darn it * plead for mercy from the testing gods, i merely wished to have named test reports, but clearly i have overreached. * pr updates, send record key * pr review * optional chaining fails tests * Apply suggestions from code review Co-authored-by: Bill Glesias <bglesias@gmail.com> * tests for cloud-span-exporter * bad merge * adding tests for the remaining exporters * note * docs * Correctly set test under the current run span for component testing * gate sending the message. * pr updates * finally, fingers crossed. --------- Co-authored-by: Emily Rohrbough <emilyrohrbough@yahoo.com> Co-authored-by: Matt Schile <mschile@cypress.io> Co-authored-by: Bill Glesias <bglesias@gmail.com>
150 lines
3.4 KiB
JavaScript
150 lines
3.4 KiB
JavaScript
require('../cwd')
|
|
|
|
const _ = require('lodash')
|
|
const EE = require('events')
|
|
const path = require('path')
|
|
const debug = require('debug')('cypress:server:preprocessor')
|
|
const Promise = require('bluebird')
|
|
const appData = require('../util/app_data')
|
|
const plugins = require('../plugins')
|
|
const { telemetry } = require('@packages/telemetry')
|
|
|
|
const errorMessage = function (err = {}) {
|
|
return err.stack || err.annotated || err.message || err.toString()
|
|
}
|
|
|
|
const clientSideError = function (err) {
|
|
// eslint-disable-next-line no-console
|
|
console.log(err.message)
|
|
|
|
err = errorMessage(err)
|
|
|
|
return `\
|
|
(function () {
|
|
Cypress.action("spec:script:error", {
|
|
type: "BUNDLE_ERROR",
|
|
error: ${JSON.stringify(err)}
|
|
})
|
|
}())\
|
|
`
|
|
}
|
|
|
|
const baseEmitter = new EE()
|
|
let fileObjects = {}
|
|
let fileProcessors = {}
|
|
|
|
plugins.registerHandler((ipc) => {
|
|
ipc.on('preprocessor:rerun', (filePath) => {
|
|
debug('ipc preprocessor:rerun event')
|
|
|
|
baseEmitter.emit('file:updated', filePath)
|
|
})
|
|
|
|
baseEmitter.on('close', (filePath) => {
|
|
debug('base emitter plugin close event')
|
|
|
|
ipc.send('preprocessor:close', filePath)
|
|
})
|
|
})
|
|
|
|
// for simpler stubbing from unit tests
|
|
const API = {
|
|
errorMessage,
|
|
|
|
clientSideError,
|
|
|
|
emitter: baseEmitter,
|
|
|
|
getFile (filePath, config) {
|
|
let fileObject; let fileProcessor
|
|
|
|
debug(`getting file ${filePath}`)
|
|
filePath = path.resolve(config.projectRoot, filePath)
|
|
|
|
debug(`getFile ${filePath}`)
|
|
|
|
if (!(fileObject = fileObjects[filePath])) {
|
|
// we should be watching the file if we are NOT
|
|
// in a text terminal aka cypress run
|
|
// TODO: rename this to config.isRunMode
|
|
// vs config.isInterativeMode
|
|
const shouldWatch = !config.isTextTerminal || Boolean(process.env.CYPRESS_INTERNAL_FORCE_FILEWATCH)
|
|
|
|
const baseFilePath = filePath.replace(config.projectRoot, '')
|
|
|
|
fileObject = (fileObjects[filePath] = _.extend(new EE(), {
|
|
filePath,
|
|
shouldWatch,
|
|
outputPath: appData.getBundledFilePath(config.projectRoot, baseFilePath),
|
|
}))
|
|
|
|
fileObject.on('rerun', () => {
|
|
debug('file object rerun event')
|
|
|
|
return baseEmitter.emit('file:updated', filePath)
|
|
})
|
|
|
|
baseEmitter.once('close', () => {
|
|
debug('base emitter native close event')
|
|
|
|
return fileObject.emit('close')
|
|
})
|
|
}
|
|
|
|
if (config.isTextTerminal && (fileProcessor = fileProcessors[filePath])) {
|
|
debug('headless and already processed')
|
|
|
|
return fileProcessor
|
|
}
|
|
|
|
const preprocessor = (fileProcessors[filePath] = Promise.try(() => {
|
|
const span = telemetry.startSpan({ name: 'file:preprocessor' })
|
|
|
|
return plugins.execute('file:preprocessor', fileObject).then((arg) => {
|
|
span?.setAttribute('file', arg)
|
|
span?.end()
|
|
|
|
return arg
|
|
})
|
|
}))
|
|
|
|
return preprocessor
|
|
},
|
|
|
|
removeFile (filePath, config) {
|
|
let fileObject
|
|
|
|
filePath = path.resolve(config.projectRoot, filePath)
|
|
|
|
if (!fileProcessors[filePath]) {
|
|
return
|
|
}
|
|
|
|
debug(`removeFile ${filePath}`)
|
|
|
|
baseEmitter.emit('close', filePath)
|
|
|
|
fileObject = fileObjects[filePath]
|
|
|
|
if (fileObject) {
|
|
fileObject.emit('close')
|
|
}
|
|
|
|
delete fileObjects[filePath]
|
|
|
|
delete fileProcessors[filePath]
|
|
},
|
|
|
|
close () {
|
|
debug('close preprocessor')
|
|
|
|
fileObjects = {}
|
|
fileProcessors = {}
|
|
baseEmitter.emit('close')
|
|
|
|
baseEmitter.removeAllListeners()
|
|
},
|
|
}
|
|
|
|
module.exports = API
|