diff --git a/packages/data-context/src/DataContext.ts b/packages/data-context/src/DataContext.ts index 25349f112be..f09635a3b24 100644 --- a/packages/data-context/src/DataContext.ts +++ b/packages/data-context/src/DataContext.ts @@ -1,4 +1,4 @@ -import type { LaunchArgs, OpenProjectLaunchOptions, PlatformName } from '@packages/types' +import type { LaunchArgs, OpenProjectLaunchOptions } from '@packages/types' import fsExtra from 'fs-extra' import path from 'path' @@ -28,7 +28,7 @@ import type { GraphQLSchema } from 'graphql' import type { Server } from 'http' import type { AddressInfo } from 'net' import EventEmitter from 'events' -import type { App as ElectronApp } from 'electron' +import type { App, App as ElectronApp } from 'electron' import { VersionsDataSource } from './sources/VersionsDataSource' const IS_DEV_ENV = process.env.CYPRESS_INTERNAL_ENV !== 'production' @@ -39,7 +39,6 @@ export interface InternalDataContextOptions { export interface DataContextConfig { schema: GraphQLSchema - os: PlatformName launchArgs: LaunchArgs launchOptions: OpenProjectLaunchOptions electronApp?: ElectronApp @@ -55,13 +54,10 @@ export interface DataContextConfig { authApi: AuthApiShape projectApi: ProjectApiShape electronApi: ElectronApiShape - /** - * Internal options used for testing purposes - */ - _internalOptions: InternalDataContextOptions } export class DataContext { + private _app?: App private _rootBus: EventEmitter private _coreData: CoreDataShape private _gqlServer?: Server @@ -73,6 +69,10 @@ export class DataContext { this._coreData = _config.coreData ?? makeCoreData() } + setElectronApp (app: App) { + this._app = app + } + get electronApp () { return this._config.electronApp } @@ -101,10 +101,8 @@ export class DataContext { this.actions.app.refreshNodePath(), ] - if (this._config._internalOptions.loadCachedProjects) { - // load projects from cache on start - toAwait.push(this.actions.project.loadProjects()) - } + // load projects from cache on start + toAwait.push(this.actions.project.loadProjects()) if (this._config.launchArgs.projectRoot) { await this.actions.project.setActiveProject(this._config.launchArgs.projectRoot) @@ -137,10 +135,6 @@ export class DataContext { return this._rootBus } - get os () { - return this._config.os - } - get launchArgs () { return this._config.launchArgs } diff --git a/packages/data-context/src/index.ts b/packages/data-context/src/index.ts index 806fc1433f7..07ff3b47c37 100644 --- a/packages/data-context/src/index.ts +++ b/packages/data-context/src/index.ts @@ -1,3 +1,5 @@ +import type { DataContext } from './DataContext' + export { DataContext, } from './DataContext' @@ -5,3 +7,49 @@ export { export type { DataContextConfig, } from './DataContext' + +let ctx: DataContext | null = null + +// globalPubSub.on('cleanup', clearCtx) + +/** + * Shouldn't ever be called from runtime code, primarily for test situations where we need to + */ +export function clearCtx () { + ctx = null +} + +/** + * Gets the current DataContext, used in situations where it's too much work + * to inject it deeply through the class hierearchy in legacy server code, but we + * need to reference it anyway, and for the time being we can assume + * there's only one for the lifecycle of the Electron app. + */ +export function getCtx () { + if (!ctx) { + throw new Error(` + Expected DataContext to already have been set via setCtx. If this is a + testing context, make sure you are calling "setCtx" in a before hook, + otherwise check the application flow. + `) + } + + return ctx +} + +/** + * Sets the current DataContext - happens at runtime when we startup Cypress + * in "open" / "run" mode, or during testing in a beforeEach, when we clear the context + */ +export function setCtx (_ctx: DataContext) { + if (ctx) { + throw new Error(` + The context has already been set. If this is occurring in a testing context, + make sure you are clearing the context. Otherwise + `) + } + + ctx = _ctx + + return _ctx +} diff --git a/packages/data-context/src/util/urqlCacheKeys.ts b/packages/data-context/src/util/urqlCacheKeys.ts index 4382c8fe386..6b36f7d82f3 100644 --- a/packages/data-context/src/util/urqlCacheKeys.ts +++ b/packages/data-context/src/util/urqlCacheKeys.ts @@ -13,6 +13,7 @@ export const urqlCacheKeys: Partial = { App: (data) => data.__typename, DevState: (data) => data.__typename, Wizard: (data) => data.__typename, + CloudRunCommitInfo: () => null, GitInfo: () => null, BaseError: () => null, ProjectPreferences: (data) => data.__typename, diff --git a/packages/driver/src/cypress/proxy-logging.ts b/packages/driver/src/cypress/proxy-logging.ts index 883f669ac4b..c7fae90016f 100644 --- a/packages/driver/src/cypress/proxy-logging.ts +++ b/packages/driver/src/cypress/proxy-logging.ts @@ -392,7 +392,10 @@ export default class ProxyLogging { const proxyRequest = new ProxyRequest(preRequest) const logConfig = getRequestLogConfig(proxyRequest as Omit) - proxyRequest.log = this.Cypress.log(logConfig).snapshot('request') + // TODO: Figure out what is causing the race condition here + if (this.Cypress.log) { + proxyRequest.log = this.Cypress.log(logConfig).snapshot('request') + } this.proxyRequests.push(proxyRequest as ProxyRequest) diff --git a/packages/frontend-shared/cypress/e2e/e2ePluginSetup.ts b/packages/frontend-shared/cypress/e2e/e2ePluginSetup.ts index 65c26974e2f..9454fe25306 100644 --- a/packages/frontend-shared/cypress/e2e/e2ePluginSetup.ts +++ b/packages/frontend-shared/cypress/e2e/e2ePluginSetup.ts @@ -2,7 +2,6 @@ import path from 'path' import type { RemoteGraphQLInterceptor, WithCtxInjected, WithCtxOptions } from './support/e2eSupport' import { e2eProjectDirs } from './support/e2eProjectDirs' import type { CloudExecuteRemote } from '@packages/data-context/src/sources' -import type { DataContext } from '@packages/data-context' import * as inspector from 'inspector' import sinonChai from '@cypress/sinon-chai' import sinon from 'sinon' @@ -14,6 +13,7 @@ import { Response } from 'cross-fetch' import { CloudRunQuery } from '../support/mock-graphql/stubgql-CloudTypes' import { getOperationName } from '@urql/core' +import type { DataContext } from '@packages/data-context' const cloudSchema = buildSchema(fs.readFileSync(path.join(__dirname, '../../../graphql/schemas/cloud.graphql'), 'utf8')) @@ -36,6 +36,7 @@ export async function e2ePluginSetup (projectRoot: string, on: Cypress.PluginEve delete process.env.CYPRESS_INTERNAL_VITE_LAUNCHPAD_PORT // require'd so we don't import the types from @packages/server which would // pollute strict type checking + const { clearCtx, makeDataContext, setCtx } = require('../../../server/lib/makeDataContext') const { runInternalServer } = require('@packages/server/lib/modes/internal-server') const Fixtures = require('@tooling/system-tests/lib/fixtures') const tmpDir = path.join(__dirname, '.projects') @@ -59,6 +60,13 @@ export async function e2ePluginSetup (projectRoot: string, on: Cypress.PluginEve let remoteGraphQLIntercept: RemoteGraphQLInterceptor | undefined on('task', { + beforeEach () { + clearCtx() + setCtx(makeDataContext({})) + remoteGraphQLIntercept = undefined + + return null + }, remoteGraphQLIntercept (fn: string) { remoteGraphQLIntercept = new Function('console', 'obj', `return (${fn})(obj)`).bind(null, console) as RemoteGraphQLInterceptor @@ -74,7 +82,7 @@ export async function e2ePluginSetup (projectRoot: string, on: Cypress.PluginEve if (obj.activeTestId !== currentTestId) { await ctx?.destroy() currentTestId = obj.activeTestId - remoteGraphQLIntercept = undefined + testState = {}; ({ serverPortPromise, ctx } = runInternalServer({ projectRoot: null, diff --git a/packages/frontend-shared/cypress/e2e/support/e2eSupport.ts b/packages/frontend-shared/cypress/e2e/support/e2eSupport.ts index 03edf66b2f5..f3e7658d3d5 100644 --- a/packages/frontend-shared/cypress/e2e/support/e2eSupport.ts +++ b/packages/frontend-shared/cypress/e2e/support/e2eSupport.ts @@ -71,6 +71,7 @@ beforeEach(() => { // Reset the ports so we know we need to call "setupE2E" before each test Cypress.env('e2e_serverPort', undefined) Cypress.env('e2e_gqlPort', undefined) + cy.task('beforeEach', { log: false }) }) // function setup @@ -131,7 +132,7 @@ function visitApp (href?: string) { } return cy.withCtx(async (ctx) => { - return JSON.stringify(ctx.html.fetchAppInitialData()) + return JSON.stringify(await ctx.html.fetchAppInitialData()) }, { log: false }).then((ssrData) => { return cy.visit(`dist-app/index.html?serverPort=${e2e_serverPort}${href || ''}`, { onBeforeLoad (win) { diff --git a/packages/server/lib/config.ts b/packages/server/lib/config.ts index 832963c0487..009eea2fb3f 100644 --- a/packages/server/lib/config.ts +++ b/packages/server/lib/config.ts @@ -17,7 +17,6 @@ import pathHelpers from './util/path_helpers' const debug = Debug('cypress:server:config') import { getProcessEnvVars, CYPRESS_SPECIAL_ENV_VARS } from './util/config' -import type { DataContext } from '@packages/data-context' const folders = _(configUtils.options).filter({ isFolder: true }).map('name').value() @@ -130,10 +129,9 @@ export type FullConfig = export function get ( projectRoot, options: { configFile?: string | false } = { configFile: undefined }, - ctx: DataContext, ): Promise { return Promise.all([ - settings.read(projectRoot, options, ctx).then(validateFile(options.configFile ?? 'cypress.config.{ts|js}')), + settings.read(projectRoot, options).then(validateFile(options.configFile ?? 'cypress.config.{ts|js}')), settings.readEnv(projectRoot).then(validateFile('cypress.env.json')), ]) .spread((settings, envFile) => { @@ -444,7 +442,10 @@ export function setSupportFileAndFolder (obj, defaults) { // /tmp/foo -> /private/tmp/foo // which can confuse the rest of the code // switch it back to "normal" file - obj.supportFile = path.join(sf, path.basename(obj.supportFile)) + const supportFileName = path.basename(obj.supportFile) + const base = sf.endsWith(supportFileName) ? path.dirname(sf) : sf + + obj.supportFile = path.join(base, supportFileName) return fs.pathExists(obj.supportFile) .then((found) => { diff --git a/packages/server/lib/makeDataContext.ts b/packages/server/lib/makeDataContext.ts index d56c90588a8..42261bf7adf 100644 --- a/packages/server/lib/makeDataContext.ts +++ b/packages/server/lib/makeDataContext.ts @@ -1,63 +1,29 @@ -import { DataContext } from '@packages/data-context' -import os from 'os' -import electron, { App } from 'electron' +import { DataContext, getCtx, setCtx, clearCtx } from '@packages/data-context' +import electron from 'electron' import specsUtil from './util/specs' -import type { AllowedState, FindSpecs, FoundBrowser, LaunchArgs, LaunchOpts, OpenProjectLaunchOptions, PlatformName, Preferences, SettingsOptions } from '@packages/types' +import type { AllowedState, FindSpecs, FoundBrowser, LaunchArgs, LaunchOpts, OpenProjectLaunchOptions, Preferences, SettingsOptions } from '@packages/types' import browserUtils from './browsers/utils' import auth from './gui/auth' import user from './user' import * as config from './config' -import { EventEmitter } from 'events' import { openProject } from './open_project' import cache from './cache' import errors from './errors' import findSystemNode from './util/find_system_node' import { graphqlSchema } from '@packages/graphql/src/schema' -import type { InternalDataContextOptions } from '@packages/data-context/src/DataContext' import { openExternal } from '@packages/server/lib/gui/links' import { getUserEditor } from './util/editors' import * as savedState from './saved_state' const { getBrowsers, ensureAndGetByNameOrPath } = browserUtils -interface MakeDataContextOptions { - electronApp?: App - os: PlatformName - rootBus: EventEmitter - launchArgs: LaunchArgs - _internalOptions: InternalDataContextOptions -} - -let legacyDataContext: DataContext | undefined - -// For testing -export async function clearLegacyDataContext () { - await legacyDataContext?.destroy() - legacyDataContext = undefined -} - -export function makeLegacyDataContext (launchArgs: LaunchArgs = {} as LaunchArgs): DataContext { - if (legacyDataContext && process.env.LAUNCHPAD) { - throw new Error(`Expected ctx to be passed as an arg, but used legacy data context`) - } else if (!legacyDataContext) { - legacyDataContext = makeDataContext({ - rootBus: new EventEmitter, - launchArgs, - os: os.platform() as PlatformName, - _internalOptions: { - loadCachedProjects: true, - }, - }) - } - - return legacyDataContext -} +export { getCtx, setCtx, clearCtx } -export function makeDataContext (options: MakeDataContextOptions): DataContext { +export function makeDataContext (launchArgs: LaunchArgs): DataContext { const ctx = new DataContext({ schema: graphqlSchema, - ...options, + launchArgs, launchOptions: {}, appApi: { getBrowsers, @@ -79,7 +45,7 @@ export function makeDataContext (options: MakeDataContextOptions): DataContext { }, projectApi: { getConfig (projectRoot: string, options?: SettingsOptions) { - return config.get(projectRoot, options, ctx) + return config.get(projectRoot, options) }, launchProject (browser: FoundBrowser, spec: Cypress.Spec, options?: LaunchOpts) { return openProject.launch({ ...browser }, spec, options) diff --git a/packages/server/lib/modes/index.ts b/packages/server/lib/modes/index.ts index 2bd54d29bac..4a97b11a1dc 100644 --- a/packages/server/lib/modes/index.ts +++ b/packages/server/lib/modes/index.ts @@ -1,9 +1,13 @@ -import { makeLegacyDataContext } from '../makeDataContext' +import { clearCtx, setCtx } from '@packages/data-context' +import { makeDataContext } from '../makeDataContext' export = (mode, options) => { - if (!process.env.LAUNCHPAD) { - makeLegacyDataContext(options) - } + // When we're in testing mode, this is setup automatically as a beforeEach + clearCtx() + + const ctx = makeDataContext(options) + + setCtx(ctx) if (mode === 'record') { return require('./record').run(options) diff --git a/packages/server/lib/modes/internal-server.ts b/packages/server/lib/modes/internal-server.ts index 8f95b1b42da..b8e343e527b 100644 --- a/packages/server/lib/modes/internal-server.ts +++ b/packages/server/lib/modes/internal-server.ts @@ -5,6 +5,7 @@ import type { App } from 'electron' import { makeDataContext } from '../makeDataContext' import { makeGraphQLServer } from '../gui/makeGraphQLServer' import { assertValidPlatform } from '@packages/types/src/platform' +import { DataContext, getCtx, setCtx } from '@packages/data-context' export function runInternalServer (launchArgs, _internalOptions = { loadCachedProjects: true }, electronApp?: App) { const bus = new EventEmitter() @@ -12,13 +13,13 @@ export function runInternalServer (launchArgs, _internalOptions = { loadCachedPr assertValidPlatform(platform) - const ctx = makeDataContext({ - electronApp, - os: platform, - rootBus: bus, - launchArgs, - _internalOptions, - }) + let ctx: DataContext + + try { + ctx = getCtx() + } catch { + ctx = setCtx(makeDataContext(launchArgs)) + } // Initializing the data context, loading browsers, etc. ctx.initializeData() diff --git a/packages/server/lib/open_project.ts b/packages/server/lib/open_project.ts index 152a6a0142c..26e1564ffdc 100644 --- a/packages/server/lib/open_project.ts +++ b/packages/server/lib/open_project.ts @@ -13,7 +13,7 @@ import { getSpecUrl } from './project_utils' import errors from './errors' import type { LaunchOpts, LaunchArgs, OpenProjectLaunchOptions, FoundBrowser } from '@packages/types' import type { DataContext } from '@packages/data-context' -import { makeLegacyDataContext } from './makeDataContext' +import { getCtx } from './makeDataContext' const debug = Debug('cypress:server:open_project') @@ -268,7 +268,7 @@ export class OpenProject { _ctx?: DataContext async create (path: string, args: LaunchArgs, options: OpenProjectLaunchOptions, browsers: FoundBrowser[] = []) { - this._ctx = options.ctx ?? makeLegacyDataContext() + this._ctx = getCtx() debug('open_project create %s', path) _.defaults(options, { diff --git a/packages/server/lib/project-base.ts b/packages/server/lib/project-base.ts index e15b831af59..a9fa3dcb542 100644 --- a/packages/server/lib/project-base.ts +++ b/packages/server/lib/project-base.ts @@ -32,8 +32,7 @@ import preprocessor from './plugins/preprocessor' import { SpecsStore } from './specs-store' import { checkSupportFile, getDefaultConfigFilePath } from './project_utils' import type { FoundBrowser, OpenProjectLaunchOptions } from '@packages/types' -import { makeLegacyDataContext } from './makeDataContext' -import type { DataContext } from '@packages/data-context' +import { DataContext, getCtx } from '@packages/data-context' // Cannot just use RuntimeConfigOptions as is because some types are not complete. // Instead, this is an interface of values that have been manually validated to exist @@ -106,7 +105,7 @@ export class ProjectBase extends EE { this.spec = null this.browser = null this.id = createHmac('sha256', 'secret-key').update(projectRoot).digest('hex') - this.ctx = options.ctx ?? makeLegacyDataContext() + this.ctx = getCtx() debug('Project created %o', { testingType: this.testingType, @@ -703,10 +702,10 @@ export class ProjectBase extends EE { async initializeConfig (browsers: FoundBrowser[] = []): Promise { // set default for "configFile" if undefined if (this.options.configFile === undefined || this.options.configFile === null) { - this.options.configFile = await getDefaultConfigFilePath(this.projectRoot, this.ctx) + this.options.configFile = await getDefaultConfigFilePath(this.projectRoot) } - let theCfg: Cfg = await config.get(this.projectRoot, this.options, this.ctx) + let theCfg: Cfg = await config.get(this.projectRoot, this.options) if (!theCfg.browsers || theCfg.browsers.length === 0) { // @ts-ignore - we don't know if the browser is headed or headless at this point. diff --git a/packages/server/lib/project_utils.ts b/packages/server/lib/project_utils.ts index 38b13fe6a08..96e002807b5 100644 --- a/packages/server/lib/project_utils.ts +++ b/packages/server/lib/project_utils.ts @@ -5,7 +5,7 @@ import * as settings from './util/settings' import errors from './errors' import { fs } from './util/fs' import { escapeFilenameInUrl } from './util/escape_filename' -import { makeLegacyDataContext } from './makeDataContext' +import { getCtx } from '@packages/data-context' const debug = Debug('cypress:server:project_utils') @@ -149,6 +149,6 @@ export const checkSupportFile = async ({ return } -export async function getDefaultConfigFilePath (projectRoot: string, ctx = makeLegacyDataContext()): Promise { - return ctx.config.getDefaultConfigBasename(projectRoot) +export async function getDefaultConfigFilePath (projectRoot: string): Promise { + return getCtx().config.getDefaultConfigBasename(projectRoot) } diff --git a/packages/server/lib/server-e2e.ts b/packages/server/lib/server-e2e.ts index 6cdd989f8fe..de0acb415b7 100644 --- a/packages/server/lib/server-e2e.ts +++ b/packages/server/lib/server-e2e.ts @@ -16,8 +16,7 @@ import * as ensureUrl from './util/ensure-url' import headersUtil from './util/headers' import statusCode from './util/status_code' import type { Cfg } from './project-base' -import { makeLegacyDataContext } from './makeDataContext' -import type { DataContext } from '@packages/data-context' +import { DataContext, getCtx } from '@packages/data-context' type WarningErr = Record @@ -46,8 +45,8 @@ const isResponseHtml = function (contentType, responseBuffer) { export class ServerE2E extends ServerBase { private _urlResolver: Bluebird> | null - constructor (ctx: DataContext = makeLegacyDataContext()) { - super(ctx) + constructor (ctx: DataContext) { + super(getCtx()) this._urlResolver = null } diff --git a/packages/server/lib/util/settings.ts b/packages/server/lib/util/settings.ts index e73e4620af5..51e09718b98 100644 --- a/packages/server/lib/util/settings.ts +++ b/packages/server/lib/util/settings.ts @@ -5,8 +5,7 @@ import errors from '../errors' import { fs } from '../util/fs' import Debug from 'debug' import type { SettingsOptions } from '@packages/types' -import type { DataContext } from '@packages/data-context' -import { makeLegacyDataContext } from '../makeDataContext' +import { getCtx } from '@packages/data-context' const debug = Debug('cypress:server:settings') @@ -140,14 +139,14 @@ export function id (projectRoot, options = {}) { }) } -export function read (projectRoot, options: SettingsOptions = {}, ctx: DataContext = makeLegacyDataContext()) { +export function read (projectRoot, options: SettingsOptions = {}) { if (options.configFile === false) { return Promise.resolve({}) } const file = pathToConfigFile(projectRoot, options) - return ctx.config.getOrCreateBaseConfig(file) + return getCtx().config.getOrCreateBaseConfig(file) .catch((err) => { if (err.type === 'MODULE_NOT_FOUND' || err.code === 'ENOENT') { return Promise.reject(errors.get('CONFIG_FILE_NOT_FOUND', options.configFile, projectRoot)) diff --git a/packages/server/test/integration/cypress_spec.js b/packages/server/test/integration/cypress_spec.js index 6c511888181..57ac8896dce 100644 --- a/packages/server/test/integration/cypress_spec.js +++ b/packages/server/test/integration/cypress_spec.js @@ -47,7 +47,7 @@ const system = require(`${root}lib/util/system`) const appData = require(`${root}lib/util/app_data`) const electronApp = require('../../lib/util/electron-app') const savedState = require(`${root}lib/saved_state`) -const { makeLegacyDataContext } = require(`${root}lib/makeDataContext`) +const { getCtx } = require(`${root}lib/makeDataContext`) const TYPICAL_BROWSERS = [ { @@ -109,7 +109,7 @@ describe('lib/cypress', () => { require('mocha-banner').register() beforeEach(function () { - ctx = makeLegacyDataContext() + ctx = getCtx() process.chdir(previousCwd) this.timeout(8000) diff --git a/packages/server/test/integration/http_requests_spec.js b/packages/server/test/integration/http_requests_spec.js index be79a85923d..8c46f3755f5 100644 --- a/packages/server/test/integration/http_requests_spec.js +++ b/packages/server/test/integration/http_requests_spec.js @@ -36,7 +36,7 @@ const Fixtures = require('@tooling/system-tests/lib/fixtures') */ const { getRunnerInjectionContents } = require(`@packages/resolve-dist`) const { createRoutes } = require(`${root}lib/routes`) -const { makeLegacyDataContext } = require(`${root}lib/makeDataContext`) +const { getCtx } = require(`${root}lib/makeDataContext`) zlib = Promise.promisifyAll(zlib) @@ -85,7 +85,7 @@ describe('Routes', () => { beforeEach(async function () { await Fixtures.scaffoldCommonNodeModules() - ctx = makeLegacyDataContext() + ctx = getCtx() process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0' sinon.stub(CacheBuster, 'get').returns('-123') diff --git a/packages/server/test/integration/plugins_spec.js b/packages/server/test/integration/plugins_spec.js index 5aff949a34f..153ea99e194 100644 --- a/packages/server/test/integration/plugins_spec.js +++ b/packages/server/test/integration/plugins_spec.js @@ -2,13 +2,13 @@ require('../spec_helper') const plugins = require('../../lib/plugins') const Fixtures = require('@tooling/system-tests/lib/fixtures') -const { makeLegacyDataContext } = require('../../lib/makeDataContext') +const { getCtx } = require('../../lib/makeDataContext') let ctx describe('lib/plugins', () => { beforeEach(async () => { - ctx = makeLegacyDataContext() + ctx = getCtx() Fixtures.scaffoldProject('plugin-before-browser-launch-deprecation') await Fixtures.scaffoldCommonNodeModules() ctx.actions.project.setActiveProjectForTestSetup(Fixtures.projectPath('plugin-before-browser-launch-deprecation')) diff --git a/packages/server/test/integration/websockets_spec.js b/packages/server/test/integration/websockets_spec.js index 980d409e904..db6223d5a85 100644 --- a/packages/server/test/integration/websockets_spec.js +++ b/packages/server/test/integration/websockets_spec.js @@ -14,7 +14,7 @@ const { SpecsStore } = require(`${root}/lib/specs-store`) const { Automation } = require(`${root}lib/automation`) const Fixtures = require('@tooling/system-tests/lib/fixtures') const { createRoutes } = require(`${root}lib/routes`) -const { makeLegacyDataContext } = require(`${root}lib/makeDataContext`) +const { getCtx } = require(`${root}lib/makeDataContext`) const cyPort = 12345 const otherPort = 55551 @@ -27,7 +27,7 @@ describe('Web Sockets', () => { require('mocha-banner').register() beforeEach(function () { - ctx = makeLegacyDataContext() + ctx = getCtx() Fixtures.scaffold() this.idsPath = Fixtures.projectPath('ids') diff --git a/packages/server/test/performance/proxy_performance_spec.js b/packages/server/test/performance/proxy_performance_spec.js index 6a281b2a8e6..2d5a8fe8af9 100644 --- a/packages/server/test/performance/proxy_performance_spec.js +++ b/packages/server/test/performance/proxy_performance_spec.js @@ -1,4 +1,7 @@ require('../spec_helper') +const { setCtx, makeDataContext } = require('../../lib/makeDataContext') + +setCtx(makeDataContext({})) const cp = require('child_process') const fse = require('fs-extra') diff --git a/packages/server/test/spec_helper.js b/packages/server/test/spec_helper.js index 8e3f24bc4f8..f5021ee5374 100644 --- a/packages/server/test/spec_helper.js +++ b/packages/server/test/spec_helper.js @@ -98,7 +98,11 @@ before(function () { // appData.ensure() +const { setCtx, getCtx, clearCtx, makeDataContext } = require('../lib/makeDataContext') + beforeEach(function () { + clearCtx() + setCtx(makeDataContext({})) this.originalEnv = originalEnv nock.disableNetConnect() @@ -109,10 +113,9 @@ beforeEach(function () { return cache.remove() }) -const { clearLegacyDataContext } = require('../lib/makeDataContext') - afterEach(async () => { - await clearLegacyDataContext() + await getCtx().destroy() + clearCtx() sinon.restore() nock.cleanAll() diff --git a/packages/server/test/unit/browsers/browsers_spec.js b/packages/server/test/unit/browsers/browsers_spec.js index 8bb20ede27d..331b2534b36 100644 --- a/packages/server/test/unit/browsers/browsers_spec.js +++ b/packages/server/test/unit/browsers/browsers_spec.js @@ -3,6 +3,7 @@ require('../../spec_helper') const browsers = require(`${root}../lib/browsers`) const utils = require(`${root}../lib/browsers/utils`) const snapshot = require('snap-shot-it') +const { EventEmitter } = require('events') const normalizeBrowsers = (message) => { return message.replace(/(found on your system are:)(?:\n- .*)*/, '$1\n- chrome\n- firefox\n- electron') @@ -22,7 +23,14 @@ after(() => { describe('lib/browsers/index', () => { context('.getBrowserInstance', () => { it('returns instance', () => { - const instance = { pid: 1234 } + const ee = new EventEmitter() + + ee.kill = () => { + ee.emit('exit') + } + + ee.pid = 1234 + const instance = ee browsers._setInstance(instance) diff --git a/packages/server/test/unit/files_spec.js b/packages/server/test/unit/files_spec.js index 5e04909d0d2..c4706e0e1a1 100644 --- a/packages/server/test/unit/files_spec.js +++ b/packages/server/test/unit/files_spec.js @@ -3,13 +3,13 @@ require('../spec_helper') const files = require('../../lib/files') const config = require('../../lib/config') const FixturesHelper = require('@tooling/system-tests/lib/fixtures') -const { makeLegacyDataContext } = require('../../lib/makeDataContext') +const { getCtx } = require('../../lib/makeDataContext') let ctx describe('lib/files', () => { beforeEach(function () { - ctx = makeLegacyDataContext() + ctx = getCtx() FixturesHelper.scaffold() this.todosPath = FixturesHelper.projectPath('todos') diff --git a/packages/server/test/unit/fixture_spec.js b/packages/server/test/unit/fixture_spec.js index 5eb96930ebf..4bc00346d02 100644 --- a/packages/server/test/unit/fixture_spec.js +++ b/packages/server/test/unit/fixture_spec.js @@ -6,7 +6,7 @@ const config = require(`${root}lib/config`) const fixture = require(`${root}lib/fixture`) const { fs } = require(`${root}lib/util/fs`) const FixturesHelper = require('@tooling/system-tests/lib/fixtures') -const { makeLegacyDataContext } = require(`${root}lib/makeDataContext`) +const { getCtx } = require(`${root}lib/makeDataContext`) const os = require('os') const eol = require('eol') @@ -18,7 +18,7 @@ let ctx describe('lib/fixture', () => { beforeEach(function () { - ctx = makeLegacyDataContext() + ctx = getCtx() FixturesHelper.scaffold() this.todosPath = FixturesHelper.projectPath('todos') diff --git a/packages/server/test/unit/plugins/index_spec.js b/packages/server/test/unit/plugins/index_spec.js index b1e7fdf0692..d2700c64efc 100644 --- a/packages/server/test/unit/plugins/index_spec.js +++ b/packages/server/test/unit/plugins/index_spec.js @@ -3,7 +3,7 @@ require('../../spec_helper') const mockedEnv = require('mocked-env') const { omit } = require('lodash') const cp = require('child_process') -const { makeLegacyDataContext } = require('../../../lib/makeDataContext') +const { getCtx } = require('../../../lib/makeDataContext') const FixturesHelper = require('@tooling/system-tests/lib/fixtures') const plugins = require('../../../lib/plugins') @@ -21,7 +21,7 @@ describe.skip('lib/plugins/index', () => { let getOptions beforeEach(() => { - ctx = makeLegacyDataContext() + ctx = getCtx() plugins._reset() FixturesHelper.scaffold() diff --git a/packages/server/test/unit/project_spec.js b/packages/server/test/unit/project_spec.js index 0824de9924e..8241376682e 100644 --- a/packages/server/test/unit/project_spec.js +++ b/packages/server/test/unit/project_spec.js @@ -21,13 +21,13 @@ const { fs } = require(`${root}lib/util/fs`) const settings = require(`${root}lib/util/settings`) const Watchers = require(`${root}lib/watchers`) const { SocketE2E } = require(`${root}lib/socket-e2e`) -const { makeLegacyDataContext } = require(`${root}lib/makeDataContext`) +const { getCtx } = require(`${root}lib/makeDataContext`) let ctx describe('lib/project-base', () => { beforeEach(function () { - ctx = makeLegacyDataContext() + ctx = getCtx() Fixtures.scaffold() this.todosPath = Fixtures.projectPath('todos') diff --git a/packages/server/test/unit/scaffold_spec.js b/packages/server/test/unit/scaffold_spec.js index fd0831a9948..530e47e7946 100644 --- a/packages/server/test/unit/scaffold_spec.js +++ b/packages/server/test/unit/scaffold_spec.js @@ -10,13 +10,13 @@ const scaffold = require(`${root}lib/scaffold`) const { fs } = require(`${root}lib/util/fs`) const glob = require(`${root}lib/util/glob`) const Fixtures = require('@tooling/system-tests/lib/fixtures') -const { makeLegacyDataContext } = require(`${root}lib/makeDataContext`) +const { getCtx } = require(`${root}lib/makeDataContext`) let ctx describe('lib/scaffold', () => { beforeEach(() => { - ctx = makeLegacyDataContext() + ctx = getCtx() return Fixtures.scaffold() }) diff --git a/packages/server/test/unit/screenshots_spec.js b/packages/server/test/unit/screenshots_spec.js index 84e560191ea..48aa230a6bf 100644 --- a/packages/server/test/unit/screenshots_spec.js +++ b/packages/server/test/unit/screenshots_spec.js @@ -12,7 +12,7 @@ const screenshots = require(`${root}lib/screenshots`) const { fs } = require(`${root}lib/util/fs`) const plugins = require(`${root}lib/plugins`) const { Screenshot } = require(`${root}lib/automation/screenshot`) -const { makeLegacyDataContext } = require(`${root}lib/makeDataContext`) +const { getCtx } = require(`${root}lib/makeDataContext`) const image = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAALlJREFUeNpi1F3xYAIDA4MBA35wgQWqyB5dRoaVmeHJ779wPhOM0aQtyBAoyglmOwmwM6z1lWY44CMDFgcBFmRTGp3EGGJe/WIQ5mZm4GRlBGJmhlm3PqGaeODpNzCtKsbGIARUCALvvv6FWw9XeOvrH4bbQNOQwfabnzHdGK3AwyAjyAqX2HPzC0Pn7Y9wPtyNIMGlD74wmAqwMZz+8AvFxzATVZAFQIqwABWQiWtgAY5uCnKAAwQYAPr8OZysiz4PAAAAAElFTkSuQmCC' const iso8601Regex = /^\d{4}\-\d{2}\-\d{2}T\d{2}\:\d{2}\:\d{2}\.?\d*Z?$/ @@ -21,7 +21,7 @@ let ctx describe('lib/screenshots', () => { beforeEach(function () { - ctx = makeLegacyDataContext() + ctx = getCtx() // make each test timeout after only 1 sec // so that durations are handled correctly this.currentTest.timeout(1000) diff --git a/packages/server/test/unit/socket_spec.js b/packages/server/test/unit/socket_spec.js index b35b588f32f..1e4feaef27d 100644 --- a/packages/server/test/unit/socket_spec.js +++ b/packages/server/test/unit/socket_spec.js @@ -18,13 +18,13 @@ const open = require(`${root}lib/util/open`) const Fixtures = require('@tooling/system-tests/lib/fixtures') const firefoxUtil = require(`${root}lib/browsers/firefox-util`).default const { createRoutes } = require(`${root}lib/routes`) -const { makeLegacyDataContext } = require(`${root}lib/makeDataContext`) +const { getCtx } = require(`${root}lib/makeDataContext`) let ctx describe('lib/socket', () => { beforeEach(function () { - ctx = makeLegacyDataContext() + ctx = getCtx() Fixtures.scaffold() this.todosPath = Fixtures.projectPath('todos') diff --git a/packages/server/test/unit/util/settings_spec.js b/packages/server/test/unit/util/settings_spec.js index fb6cc2384b4..f9329aa621a 100644 --- a/packages/server/test/unit/util/settings_spec.js +++ b/packages/server/test/unit/util/settings_spec.js @@ -3,7 +3,7 @@ const path = require('path') require('../../spec_helper') const { fs } = require('../../../lib/util/fs') const settings = require(`../../../lib/util/settings`) -const { makeLegacyDataContext } = require('../../../lib/makeDataContext') +const { getCtx } = require('../../../lib/makeDataContext') const projectRoot = process.cwd() const defaultOptions = { @@ -14,7 +14,7 @@ let ctx describe('lib/util/settings', () => { beforeEach(() => { - ctx = makeLegacyDataContext() + ctx = getCtx() }) context('with default configFile option', () => { diff --git a/packages/server/test/unit/util/specs_spec.js b/packages/server/test/unit/util/specs_spec.js index 2ade944dd46..e349bde20db 100644 --- a/packages/server/test/unit/util/specs_spec.js +++ b/packages/server/test/unit/util/specs_spec.js @@ -6,13 +6,13 @@ const config = require('../../../lib/config') const specsUtil = require(`${root}../lib/util/specs`).default const FixturesHelper = require('@tooling/system-tests/lib/fixtures') const debug = require('debug')('test') -const { makeLegacyDataContext } = require('../../../lib/makeDataContext') +const { getCtx } = require('../../../lib/makeDataContext') let ctx describe('lib/util/specs', () => { beforeEach(function () { - ctx = makeLegacyDataContext() + ctx = getCtx() FixturesHelper.scaffold() this.todosPath = FixturesHelper.projectPath('todos') diff --git a/packages/types/package.json b/packages/types/package.json index e69b871e715..318cd0bb283 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -11,6 +11,7 @@ }, "dependencies": {}, "devDependencies": { + "@types/node": "14.14.31", "rimraf": "3.0.2", "typescript": "^4.2.3" }, diff --git a/packages/types/src/platform.ts b/packages/types/src/platform.ts index bcd45914369..ac4e257b5e0 100644 --- a/packages/types/src/platform.ts +++ b/packages/types/src/platform.ts @@ -1,3 +1,4 @@ +/// export const SUPPORTED_PLATFORMS = ['linux', 'darwin', 'win32'] as const export type PlatformName = typeof SUPPORTED_PLATFORMS[number] diff --git a/packages/types/src/server.ts b/packages/types/src/server.ts index 4c298edadda..b3d5a4ec2ce 100644 --- a/packages/types/src/server.ts +++ b/packages/types/src/server.ts @@ -1,4 +1,3 @@ -import type { DataContext } from '@packages/data-context' import type { FoundBrowser } from './browser' import type { PlatformName } from './platform' @@ -56,7 +55,6 @@ export interface AutomationMiddleware { type WebSocketOptionsCallback = (...args: any[]) => any export interface OpenProjectLaunchOptions { - ctx?: DataContext args?: LaunchArgs /** * Whether to skip the plugin initialization, useful when diff --git a/scripts/circle-cache.js b/scripts/circle-cache.js index 71be0e42dae..d4fbb0fb0d3 100644 --- a/scripts/circle-cache.js +++ b/scripts/circle-cache.js @@ -36,7 +36,7 @@ const packageGlobs = workspacePaths.filter((s) => s.endsWith('/*')) async function cacheKey () { const yarnLocks = [p('yarn.lock')] const patchFiles = glob.sync(p('**/*.patch'), { - ignore: ['**/node_modules/**', '**/*_node_modules/**'], + ignore: ['**/node_modules/**', '**/*_node_modules/**', '**/dist-{app,launchpad}/**'], }) const packageJsons = glob.sync(`${BASE_DIR}/{.,${workspacePaths.join(',')}}/package.json`)