Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

fix: revert #26452 (Yarn Plug n Play compat regression) #26735

Merged
merged 3 commits into from
May 12, 2023
Merged
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
2 changes: 1 addition & 1 deletion cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ _Released 05/14/2023 (PENDING)_

**Bugfixes:**

- Reverted [#26452](https://github.com/cypress-io/cypress/pull/26630) which introduced a bug that prevents users from using End to End with Yarn 3. Fixed in [#26735](https://github.com/cypress-io/cypress/pull/26735). Fixes [#26676](https://github.com/cypress-io/cypress/issues/26676).
- Moved `types` condition to the front of `package.json#exports` since keys there are meant to be order-sensitive. Fixed in [#26630](https://github.com/cypress-io/cypress/pull/26630).

## 12.12.0
Expand Down Expand Up @@ -64,7 +65,6 @@ _Released 04/17/2023_
- Fixed an issue in the onboarding wizard where project framework & bundler would not be auto-detected when opening directly into component testing mode using the `--component` CLI flag. Fixes [#22777](https://github.com/cypress-io/cypress/issues/22777) and [#26388](https://github.com/cypress-io/cypress/issues/26388).
- Updated to use the `SEMAPHORE_GIT_WORKING_BRANCH` [Semphore](https://docs.semaphoreci.com) CI environment variable to correctly associate a Cloud run to the current branch. Previously this was incorrectly associating a run to the target branch. Fixes [#26309](https://github.com/cypress-io/cypress/issues/26309).
- Fix an edge case in Component Testing where a custom `baseUrl` in `tsconfig.json` for Next.js 13.2.0+ is not respected. This was partially fixed in [#26005](https://github.com/cypress-io/cypress/pull/26005), but an edge case was missed. Fixes [#25951](https://github.com/cypress-io/cypress/issues/25951).
- Correctly detect and resolve dependencies when configuring Component Testing in projects using Yarn's [Plug'n'Play feature](https://yarnpkg.com/features/pnp). Fixes [#25960](https://github.com/cypress-io/cypress/issues/25960).
- Fixed an issue where `click` events fired on `.type('{enter}')` did not propagate through shadow roots. Fixes [#26392](https://github.com/cypress-io/cypress/issues/26392).

**Misc:**
Expand Down
5 changes: 4 additions & 1 deletion packages/launchpad/cypress/e2e/project-setup.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,10 @@ describe('Launchpad: Setup Project', () => {
cy.findByDisplayValue('pnpm install -D react-scripts react-dom react')
})

it('works with Yarn 3 Plug n Play', () => {
// TODO: Had to revert due to regression: https://github.com/cypress-io/cypress/pull/26452
// Would be great to fully support Plug n Play eventually, but right now it causes issues relating
// to not correctly detecting dependencies when installing the binary.
it.skip('works with Yarn 3 Plug n Play', () => {
scaffoldAndOpenProject('yarn-v3.1.1-pnp')

cy.visitLaunchpad()
Expand Down
41 changes: 40 additions & 1 deletion packages/scaffold-config/src/ct-detect-third-party.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { z } from 'zod'
import fs from 'fs-extra'
import Debug from 'debug'
import findUp from 'find-up'
import { isRepositoryRoot } from './searchUtils'

const debug = Debug('cypress:scaffold-config:ct-detect-third-party')

Expand All @@ -27,6 +26,46 @@ const thirdPartyDefinitionPrefixes = {
globalPrefix: 'cypress-ct-',
}

const ROOT_PATHS = [
'.git',

// https://pnpm.io/workspaces
'pnpm-workspace.yaml',

// https://rushjs.io/pages/advanced/config_files/
'rush.json',

// https://nx.dev/deprecated/workspace-json#workspace.json
// https://nx.dev/reference/nx-json#nx.json
'workspace.json',
'nx.json',

// https://lerna.js.org/docs/api-reference/configuration
'lerna.json',
]

async function hasWorkspacePackageJson (directory: string) {
try {
const pkg = await fs.readJson(path.join(directory, 'package.json'))

debug('package file for %s: %o', directory, pkg)

return !!pkg.workspaces
} catch (e) {
debug('error reading package.json in %s. this is not the repository root', directory)

return false
}
}

export async function isRepositoryRoot (directory: string) {
if (ROOT_PATHS.some((rootPath) => fs.existsSync(path.join(directory, rootPath)))) {
return true
}

return hasWorkspacePackageJson(directory)
}

export function isThirdPartyDefinition (definition: Cypress.ComponentFrameworkDefinition | Cypress.ThirdPartyComponentFrameworkDefinition): boolean {
return definition.type.startsWith(thirdPartyDefinitionPrefixes.globalPrefix) ||
thirdPartyDefinitionPrefixes.namespacedPrefixRe.test(definition.type)
Expand Down
31 changes: 3 additions & 28 deletions packages/scaffold-config/src/frameworks.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import fs from 'fs-extra'
import * as dependencies from './dependencies'
import componentIndexHtmlGenerator from './component-index-template'
import debugLib from 'debug'
import semver from 'semver'
import { isThirdPartyDefinition } from './ct-detect-third-party'
import { tryToFindPnpFile } from './searchUtils'
import resolvePackagePath from 'resolve-package-path'

const debug = debugLib('cypress:scaffold-config:frameworks')

Expand All @@ -13,36 +14,10 @@ export type WizardBundler = typeof dependencies.WIZARD_BUNDLERS[number]

export type CodeGenFramework = Cypress.ResolvedComponentFrameworkDefinition['codeGenFramework']

const yarnPnpRegistrationPath = new Map<string, boolean>()

async function readPackageJson (packageFilePath: string, projectPath: string): Promise<PkgJson> {
return require(require.resolve(packageFilePath))
}

export async function isDependencyInstalled (dependency: Cypress.CypressComponentDependency, projectPath: string): Promise<Cypress.DependencyToInstall> {
try {
debug('detecting %s in %s', dependency.package, projectPath)

// we only need to register this once, when the project check dependencies for the first time.
if (!yarnPnpRegistrationPath.get(projectPath)) {
const pnpFile = await tryToFindPnpFile(projectPath)

if (pnpFile) {
const pnpapi = require(pnpFile)

pnpapi.setup()
yarnPnpRegistrationPath.set(projectPath, true)
} else {
// not using Yarn PnP
yarnPnpRegistrationPath.set(projectPath, false)
}
}

// NOTE: this *must* be required **after** the call to `pnpapi.setup()`
// or the pnpapi module that is added at runtime by Yarn PnP will not be correctly used
// for module resolution.
const resolvePackagePath = require('resolve-package-path')

const packageFilePath = resolvePackagePath(dependency.package, projectPath)

if (!packageFilePath) {
Expand All @@ -55,7 +30,7 @@ export async function isDependencyInstalled (dependency: Cypress.CypressComponen
}
}

const pkg = await readPackageJson(packageFilePath, projectPath)
const pkg = await fs.readJson(packageFilePath) as PkgJson

debug('found package.json %o', pkg)

Expand Down
71 changes: 0 additions & 71 deletions packages/scaffold-config/src/searchUtils.ts

This file was deleted.

62 changes: 61 additions & 1 deletion packages/scaffold-config/test/unit/ct-detect-third-party.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { scaffoldMigrationProject, fakeDepsInNodeModules } from './detect.spec'
import fs from 'fs-extra'
import path from 'path'
import { detectThirdPartyCTFrameworks, validateThirdPartyModule, isThirdPartyDefinition } from '../../src'
import { detectThirdPartyCTFrameworks, validateThirdPartyModule, isThirdPartyDefinition, isRepositoryRoot } from '../../src'
import { expect } from 'chai'
import os from 'os'
import solidJs from './fixtures'

async function copyNodeModule (root, moduleName) {
Expand Down Expand Up @@ -53,6 +54,65 @@ describe('isThirdPartyDefinition', () => {
})
})

describe('isRepositoryRoot', () => {
const TEMP_DIR = path.join(os.tmpdir(), 'is-repository-root-tmp')

beforeEach(async () => {
await fs.mkdir(TEMP_DIR)
})

afterEach(async () => {
await fs.rm(TEMP_DIR, { recursive: true })
})

it('returns false if there is nothing in the directory', async () => {
const isCurrentRepositoryRoot = await isRepositoryRoot(TEMP_DIR)

expect(isCurrentRepositoryRoot).to.be.false
})

it('returns true if there is a Git directory', async () => {
await fs.mkdir(path.join(TEMP_DIR, '.git'))

const isCurrentRepositoryRoot = await isRepositoryRoot(TEMP_DIR)

expect(isCurrentRepositoryRoot).to.be.true
})

it('returns false if there is a package.json without workspaces field', async () => {
await fs.writeFile(path.join(TEMP_DIR, 'package.json'), `{
"name": "@packages/foo",
"private": true,
"version": "1.0.0",
"main": "index.js",
"license": "MIT"
}
`)

const isCurrentRepositoryRoot = await isRepositoryRoot(TEMP_DIR)

expect(isCurrentRepositoryRoot).to.be.false
})

it('returns true if there is a package.json with workspaces field', async () => {
await fs.writeFile(path.join(TEMP_DIR, 'package.json'), `{
"name": "monorepo-repo",
"private": true,
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"workspaces": [
"packages/*"
]
}
`)

const isCurrentRepositoryRoot = await isRepositoryRoot(TEMP_DIR)

expect(isCurrentRepositoryRoot).to.be.true
})
})

describe('detectThirdPartyCTFrameworks', () => {
it('detects third party frameworks in global namespace', async () => {
const projectRoot = await scaffoldQwikApp(['cypress-ct-qwik'])
Expand Down
105 changes: 0 additions & 105 deletions packages/scaffold-config/test/unit/searchUtils.spec.ts

This file was deleted.

Loading