Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

chore: pass file preprocesor override to protocol as debug data #31171

Open
wants to merge 3 commits into
base: ryanm/chore/studio-types
Choose a base branch
from
Open
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
12 changes: 12 additions & 0 deletions packages/data-context/src/data/ProjectConfigIpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ export interface SerializedLoadConfigReply {
requires: string[]
}

export interface DebugData {
filePreprocessorHandlerString?: string
}

/**
* The ProjectConfigIpc is an EventEmitter wrapping the childProcess,
* adding a "send" method for sending events from the parent process into the childProcess,
Expand All @@ -65,6 +69,7 @@ export class ProjectConfigIpc extends EventEmitter {
readonly configFile: string | false,
readonly onError: (cypressError: CypressError, title?: string | undefined) => void,
readonly onWarning: (cypressError: CypressError) => void,
readonly onDebugData: (debugData: DebugData) => void,
) {
super()
this._childProcess = this.forkConfigProcess()
Expand Down Expand Up @@ -131,6 +136,7 @@ export class ProjectConfigIpc extends EventEmitter {
*/
once(evt: 'setupTestingType:reply', listener: (payload: SetupNodeEventsReply) => void): this
once(evt: 'setupTestingType:error', listener: (error: CypressError) => void): this
once(evt: 'file:preprocessor:overridden', listener: (payload: { handlerString: string }) => void): this
once (evt: string, listener: (...args: any[]) => void) {
return super.once(evt, listener)
}
Expand Down Expand Up @@ -238,6 +244,12 @@ export class ProjectConfigIpc extends EventEmitter {
reject(err)
})

this.once('file:preprocessor:overridden', ({ handlerString }) => {
this.onDebugData({
filePreprocessorHandlerString: handlerString,
})
})

const handleWarning = (warningErr: CypressError) => {
debug('plugins process warning:', warningErr.stack)

Expand Down
15 changes: 14 additions & 1 deletion packages/data-context/src/data/ProjectConfigManager.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { CypressError, getError } from '@packages/errors'
import { IpcHandler, LoadConfigReply, ProjectConfigIpc, SetupNodeEventsReply } from './ProjectConfigIpc'
import { DebugData, IpcHandler, LoadConfigReply, ProjectConfigIpc, SetupNodeEventsReply } from './ProjectConfigIpc'
import assert from 'assert'
import type { AllModeOptions, FullConfig, TestingType } from '@packages/types'
import debugLib from 'debug'
Expand Down Expand Up @@ -57,6 +57,7 @@ export class ProjectConfigManager {
private _loadConfigPromise: Promise<LoadConfigReply> | undefined
private _cachedLoadConfig: LoadConfigReply | undefined
private _cypressEnv: CypressEnv
private _debugData: DebugData

constructor (private options: ProjectConfigManagerOptions) {
this._cypressEnv = new CypressEnv({
Expand All @@ -66,9 +67,15 @@ export class ProjectConfigManager {
},
})

this._debugData = {}

return autoBindDebug(this)
}

get debugData () {
return this._debugData
}

get isLoadingNodeEvents () {
return this._state === 'loadingNodeEvents'
}
Expand Down Expand Up @@ -372,6 +379,12 @@ export class ProjectConfigManager {
this.options.ctx.onError(cypressError, title)
},
this.options.ctx.onWarning,
(debugData: DebugData) => {
this._debugData = {
...this._debugData,
...debugData,
}
},
)

this._loadConfigPromise = this._eventsIpc.loadConfig()
Expand Down
4 changes: 4 additions & 0 deletions packages/data-context/src/data/ProjectLifecycleManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ export class ProjectLifecycleManager {
return this.ctx.coreData.currentProjectGitInfo
}

get configDebugData () {
return this._configManager?.debugData
}

async getProjectId (): Promise<string | null> {
try {
// No need to kick off config initialization if we need to migrate
Expand Down
3 changes: 3 additions & 0 deletions packages/data-context/test/unit/data/ProjectConfigIpc.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ describe('ProjectConfigIpc', () => {
false,
(error) => {},
() => {},
() => {},
)
})

Expand Down Expand Up @@ -74,6 +75,7 @@ describe('ProjectConfigIpc', () => {
false,
(error) => {},
() => {},
() => {},
)

expect(forkSpy).to.have.been.calledWith(sinon.match.string, sinon.match.array, sinon.match({
Expand Down Expand Up @@ -116,6 +118,7 @@ describe('ProjectConfigIpc', () => {
false,
(error) => {},
() => {},
() => {},
)

expect(forkSpy).to.have.been.calledWith(sinon.match.string, sinon.match.array, sinon.match({
Expand Down
1 change: 1 addition & 0 deletions packages/server/lib/cloud/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,7 @@ export default {
},
projectConfig: _.pick(config, ['devServerPublicPathRoute', 'port', 'proxyUrl', 'namespace']),
mountVersion: runnerCapabilities.protocolMountVersion,
debugData: options.project.configDebugData,
})
}

Expand Down
8 changes: 6 additions & 2 deletions packages/server/lib/plugins/child/run_plugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class RunPlugins {

// we track the register calls and then send them all at once
// to the parent process
const registerChildEvent = (event, handler) => {
const registerChildEvent = (event, handler, isDefaultHandler = false) => {
const { isValid, userEvents, error } = validateEvent(event, handler, initialConfig)

if (!isValid) {
Expand Down Expand Up @@ -97,6 +97,10 @@ class RunPlugins {
}
}

if (event === 'file:preprocessor' && !isDefaultHandler) {
this.ipc.send('file:preprocessor:overridden', { handlerString: handler.toString() })
}

const eventId = this.eventIdCount++

this.registeredEventsById[eventId] = { event, handler }
Expand Down Expand Up @@ -124,7 +128,7 @@ class RunPlugins {
.tap(() => {
if (!this.registeredEventsByName['file:preprocessor']) {
debug('register default preprocessor')
registerChildEvent('file:preprocessor', this._getDefaultPreprocessor(initialConfig))
registerChildEvent('file:preprocessor', this._getDefaultPreprocessor(initialConfig), true)
}
})
.then((modifiedCfg) => {
Expand Down
4 changes: 4 additions & 0 deletions packages/server/lib/project-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,10 @@ export class ProjectBase extends EE {
return getCtx().lifecycleManager.getProjectId()
}

get configDebugData () {
return this.ctx.lifecycleManager.configDebugData
}

// For testing
// Do not use this method outside of testing
// pass all your options when you create a new instance!
Expand Down
14 changes: 14 additions & 0 deletions packages/server/test/unit/cloud/api/api_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,11 @@ describe('lib/cloud/api', () => {
namespace: '__cypress',
}
},
get configDebugData () {
return {
filePreprocessorHandlerString: 'function () {}',
}
},
}

return api.createRun({
Expand Down Expand Up @@ -631,6 +636,9 @@ describe('lib/cloud/api', () => {
proxyUrl: 'http://localhost:1234',
namespace: '__cypress',
},
debugData: {
filePreprocessorHandlerString: 'function () {}',
},
},
)
})
Expand Down Expand Up @@ -688,6 +696,9 @@ describe('lib/cloud/api', () => {
namespace: '__cypress',
}
},
configDebugData: {
filePreprocessorHandlerString: 'function () {}',
},
}

return api.createRun({
Expand Down Expand Up @@ -720,6 +731,9 @@ describe('lib/cloud/api', () => {
proxyUrl: 'http://localhost:1234',
namespace: '__cypress',
},
debugData: {
filePreprocessorHandlerString: 'function () {}',
},
},
)
})
Expand Down
3 changes: 3 additions & 0 deletions packages/types/src/protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ export type ProtocolManagerOptions = {
}
projectConfig: ProjectConfig
mountVersion?: number
debugData?: {
filePreprocessorHandlerString?: string
}
}

type UploadCaptureArtifactResult = {
Expand Down
3 changes: 3 additions & 0 deletions system-tests/__snapshots__/protocol_spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
exports['e2e events'] = `
{
"debugData": {},
"beforeSpec": [
{
"name": "/path/to/name",
Expand Down Expand Up @@ -6138,6 +6139,7 @@ exports['e2e events'] = `

exports['component events - experimentalSingleTabRunMode: true'] = `
{
"debugData": {},
"beforeSpec": [
{
"name": "/path/to/name",
Expand Down Expand Up @@ -7956,6 +7958,7 @@ exports['component events - experimentalSingleTabRunMode: true'] = `

exports['component events - experimentalSingleTabRunMode: false'] = `
{
"debugData": {},
"beforeSpec": [
{
"name": "/path/to/name",
Expand Down
7 changes: 6 additions & 1 deletion system-tests/lib/protocol-stubs/protocolStub.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import path from 'path'
import fs from 'fs-extra'
import type { AppCaptureProtocolInterface, ResponseEndedWithEmptyBodyOptions, ResponseStreamOptions, ResponseStreamTimedOutOptions } from '@packages/types'
import type { AppCaptureProtocolInterface, ProtocolManagerOptions, ResponseEndedWithEmptyBodyOptions, ResponseStreamOptions, ResponseStreamTimedOutOptions } from '@packages/types'
import type { Readable } from 'stream'

const getFilePath = (filename) => {
Expand Down Expand Up @@ -33,6 +33,7 @@ const DURATIONS = {
export class AppCaptureProtocol implements AppCaptureProtocolInterface {
private filename: string
private events = {
debugData: {},
beforeSpec: [],
afterSpec: [],
beforeTest: [],
Expand All @@ -52,6 +53,10 @@ export class AppCaptureProtocol implements AppCaptureProtocolInterface {
private cdpClient: any
private scriptToEvaluateId: any

constructor (options: ProtocolManagerOptions) {
this.events.debugData = options.debugData
}

getDbMetadata (): { offset: number, size: number } {
return {
offset: 0,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { defineConfig } from 'cypress'

export default defineConfig({
projectId: 'pid123',
e2e: {
supportFile: false,
setupNodeEvents: (on, config) => {
on('file:preprocessor', (file) => {
return file.filePath
})

return config
},
},
component: {
devServer: {
framework: 'react',
bundler: 'webpack',
webpackConfig: {
module: {
rules: [
{
test: /\.(js|jsx|ts|tsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react',
'@babel/preset-typescript',
],
},
},
},
{
test: /\.css$/i,
use: ['style-loader', 'css-loader'],
},
],
},
},
},
},
})
16 changes: 16 additions & 0 deletions system-tests/test/protocol_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,22 @@ describe('capture-protocol', () => {
fs.removeSync(getFilePath('e9e81b5e-cc58-4026-b2ff-8ae3161435a6.db'))
})
})

it('verifies that the debug data is correct', async function () {
await systemTests.exec(this, {
key: 'f858a2bc-b469-4e48-be67-0876339ee7e1',
project: 'protocol',
spec: 'protocol.cy.js',
record: true,
expectedExitCode: 0,
port: 2121,
configFile: 'cypress-with-file-preprocessor.config.ts',
})

const protocolEvents = await fs.promises.readFile(getFilePath('e9e81b5e-cc58-4026-b2ff-8ae3161435a6.db'), 'utf8')

expect(JSON.parse(protocolEvents).debugData.filePreprocessorHandlerString).to.equal('(file) => {\n return file.filePath;\n }')
})
})

describe('component', () => {
Expand Down