mirror of
https://github.com/cypress-io/cypress.git
synced 2026-01-06 06:29:45 -06:00
test: node_modules installs for system-tests, other improvements (#18574)
Co-authored-by: Emily Rohrbough <emilyrohrbough@users.noreply.github.com>
This commit is contained in:
67
circle.yml
67
circle.yml
@@ -149,6 +149,55 @@ commands:
|
||||
name: Restore all node_modules to proper workspace folders
|
||||
command: node scripts/circle-cache.js --action unpack
|
||||
|
||||
restore_cached_system_tests_deps:
|
||||
description: 'Restore the cached node_modules for projects in "system-tests/projects/**"'
|
||||
steps:
|
||||
- run:
|
||||
name: Generate Circle Cache key for system tests
|
||||
command: ./system-tests/scripts/cache-key.sh > system_tests_cache_key
|
||||
- restore_cache:
|
||||
name: Restore system tests node_modules cache
|
||||
keys:
|
||||
- v{{ .Environment.CACHE_VERSION }}-{{ arch }}-system-tests-projects-node-modules-cache-{{ checksum "system_tests_cache_key" }}
|
||||
- v{{ .Environment.CACHE_VERSION }}-{{ arch }}-system-tests-projects-node-modules-cache-
|
||||
|
||||
update_cached_system_tests_deps:
|
||||
description: 'Update the cached node_modules for projects in "system-tests/projects/**"'
|
||||
steps:
|
||||
- run:
|
||||
name: Generate Circle Cache key for system tests
|
||||
command: ./system-tests/scripts/cache-key.sh > system_tests_cache_key
|
||||
- restore_cache:
|
||||
name: Restore cache state, to check for known modules cache existence
|
||||
keys:
|
||||
- v{{ .Environment.CACHE_VERSION }}-{{ arch }}-system-tests-projects-node-modules-cache-state-{{ checksum "system_tests_cache_key" }}
|
||||
- run:
|
||||
name: Bail if specific cache exists
|
||||
command: |
|
||||
if [[ -f "system_tests_node_modules_installed" ]]; then
|
||||
echo "No updates to system tests node modules, exiting"
|
||||
circleci-agent step halt
|
||||
fi
|
||||
- restore_cache:
|
||||
name: Restore system tests node_modules cache
|
||||
keys:
|
||||
- v{{ .Environment.CACHE_VERSION }}-{{ arch }}-system-tests-projects-node-modules-cache-{{ checksum "system_tests_cache_key" }}
|
||||
- v{{ .Environment.CACHE_VERSION }}-{{ arch }}-system-tests-projects-node-modules-cache-
|
||||
- run:
|
||||
name: Update system-tests node_modules cache
|
||||
command: yarn workspace @tooling/system-tests projects:yarn:install
|
||||
- save_cache:
|
||||
name: Save system tests node_modules cache
|
||||
key: v{{ .Environment.CACHE_VERSION }}-{{ arch }}-system-tests-projects-node-modules-cache-{{ checksum "system_tests_cache_key" }}
|
||||
paths:
|
||||
- ~/.cache/cy-system-tests-node-modules
|
||||
- run: touch system_tests_node_modules_installed
|
||||
- save_cache:
|
||||
name: Save system tests node_modules cache state key
|
||||
key: v{{ .Environment.CACHE_VERSION }}-{{ arch }}-system-tests-projects-node-modules-cache-state-{{ checksum "system_tests_cache_key" }}
|
||||
paths:
|
||||
- system_tests_node_modules_installed
|
||||
|
||||
caching-dependency-installer:
|
||||
description: 'Installs & caches the dependencies based on yarn lock & package json dependencies'
|
||||
parameters:
|
||||
@@ -427,6 +476,7 @@ commands:
|
||||
type: string
|
||||
steps:
|
||||
- restore_cached_workspace
|
||||
- restore_cached_system_tests_deps
|
||||
- run:
|
||||
name: Run system tests
|
||||
command: |
|
||||
@@ -1083,6 +1133,12 @@ jobs:
|
||||
path: /tmp/artifacts
|
||||
- store-npm-logs
|
||||
|
||||
system-tests-node-modules-install:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- restore_cached_workspace
|
||||
- update_cached_system_tests_deps
|
||||
|
||||
system-tests-chrome:
|
||||
<<: *defaults
|
||||
resource_class: medium
|
||||
@@ -2007,19 +2063,22 @@ linux-workflow: &linux-workflow
|
||||
- server-performance-tests:
|
||||
requires:
|
||||
- build
|
||||
- system-tests-node-modules-install:
|
||||
requires:
|
||||
- build
|
||||
- system-tests-chrome:
|
||||
requires:
|
||||
- build
|
||||
- system-tests-node-modules-install
|
||||
- system-tests-electron:
|
||||
requires:
|
||||
- build
|
||||
- system-tests-node-modules-install
|
||||
- system-tests-firefox:
|
||||
requires:
|
||||
- build
|
||||
- system-tests-node-modules-install
|
||||
- system-tests-non-root:
|
||||
executor: non-root-docker-user
|
||||
requires:
|
||||
- build
|
||||
- system-tests-node-modules-install
|
||||
- driver-integration-tests-chrome:
|
||||
requires:
|
||||
- build
|
||||
|
||||
@@ -17,7 +17,15 @@ export const overrideSourceMaps = (sourceMap: boolean, typescriptPath?: string)
|
||||
return
|
||||
}
|
||||
|
||||
const typescript = require(typescriptPath || 'typescript') as typeof import('typescript')
|
||||
// when using webpack-preprocessor as a local filesystem dependency (`file:...`),
|
||||
// require(typescript) will resolve to this repo's `typescript` devDependency, not the
|
||||
// targeted project's `typescript`, which breaks monkeypatching. resolving from the
|
||||
// CWD avoids this issue.
|
||||
const projectTsPath = require.resolve(typescriptPath || 'typescript', {
|
||||
paths: [process.cwd()],
|
||||
})
|
||||
|
||||
const typescript = require(projectTsPath) as typeof import('typescript')
|
||||
const { createProgram } = typescript
|
||||
|
||||
debug('typescript found, overriding typescript.createProgram()')
|
||||
|
||||
@@ -147,7 +147,7 @@ describe('./lib/typescript-overrides', () => {
|
||||
const err = typescriptOverrides.overrideSourceMaps(true)
|
||||
|
||||
expect(err).to.be.instanceOf(Error)
|
||||
expect(err.message).to.eq(`Cannot find module 'typescript'`)
|
||||
expect(err.message).to.match(/Cannot find module '.*typescript\.js'/)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -42,7 +42,7 @@ const init = (config, options) => {
|
||||
|
||||
// test and warn for incompatible plugin
|
||||
try {
|
||||
const retriesPluginPath = path.dirname(resolve.sync('cypress-plugin-retries', {
|
||||
const retriesPluginPath = path.dirname(resolve.sync('cypress-plugin-retries/package.json', {
|
||||
basedir: options.projectRoot,
|
||||
}))
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ zlib = Promise.promisifyAll(zlib)
|
||||
// force supertest-session to use promises provided in supertest
|
||||
const session = proxyquire('supertest-session', { supertest })
|
||||
|
||||
const absolutePathRegex = /"\/[^{}]*?\.projects/g
|
||||
const absolutePathRegex = /"\/[^{}]*?cy-projects/g
|
||||
let sourceMapRegex = /\n\/\/# sourceMappingURL\=.*/
|
||||
|
||||
const replaceAbsolutePaths = (content) => {
|
||||
|
||||
@@ -6,8 +6,9 @@ const Fixtures = require('@tooling/system-tests/lib/fixtures')
|
||||
const pluginsFile = Fixtures.projectPath('plugin-before-browser-launch-deprecation/cypress/plugins/index.js')
|
||||
|
||||
describe('lib/plugins', () => {
|
||||
beforeEach(() => {
|
||||
Fixtures.scaffold()
|
||||
beforeEach(async () => {
|
||||
Fixtures.scaffoldProject('plugin-before-browser-launch-deprecation')
|
||||
await Fixtures.scaffoldCommonNodeModules()
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
|
||||
@@ -25,7 +25,7 @@ describe('lib/files', () => {
|
||||
return files.readFile(this.projectRoot, 'tests/_fixtures/message.txt').then(({ contents, filePath }) => {
|
||||
expect(contents).to.eq('foobarbaz')
|
||||
|
||||
expect(filePath).to.include('/.projects/todos/tests/_fixtures/message.txt')
|
||||
expect(filePath).to.include('/cy-projects/todos/tests/_fixtures/message.txt')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -69,7 +69,7 @@ describe('lib/files', () => {
|
||||
return files.readFile(this.projectRoot, '.projects/write_file.txt').then(({ contents, filePath }) => {
|
||||
expect(contents).to.equal('foo')
|
||||
|
||||
expect(filePath).to.include('/.projects/todos/.projects/write_file.txt')
|
||||
expect(filePath).to.include('/cy-projects/todos/.projects/write_file.txt')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -159,21 +159,24 @@ const runFailingProjectTest = function (buildAppExecutable, e2e) {
|
||||
.then(verifyScreenshots)
|
||||
}
|
||||
|
||||
const test = function (buildAppExecutable) {
|
||||
Fixtures.scaffold()
|
||||
|
||||
const test = async function (buildAppExecutable) {
|
||||
await Fixtures.scaffoldCommonNodeModules()
|
||||
Fixtures.scaffoldProject('e2e')
|
||||
const e2e = Fixtures.projectPath('e2e')
|
||||
|
||||
return runSmokeTest(buildAppExecutable)
|
||||
.then(() => {
|
||||
return runProjectTest(buildAppExecutable, e2e)
|
||||
}).then(() => {
|
||||
return runFailingProjectTest(buildAppExecutable, e2e)
|
||||
}).then(() => {
|
||||
return Fixtures.remove()
|
||||
})
|
||||
await runSmokeTest(buildAppExecutable)
|
||||
await runProjectTest(buildAppExecutable, e2e)
|
||||
await runFailingProjectTest(buildAppExecutable, e2e)
|
||||
Fixtures.remove()
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
test,
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
const buildAppExecutable = path.join(__dirname, `../../build/${os.platform()}-unpacked/Cypress`)
|
||||
|
||||
console.log('Script invoked directly, running smoke tests.')
|
||||
test(buildAppExecutable)
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ These tests launch the [Cypress server](../packages/server) process for each tes
|
||||
|
||||
These tests run in CI in Electron, Chrome, and Firefox under the `system-tests` job family.
|
||||
|
||||
## Running system tests
|
||||
## Running System Tests
|
||||
|
||||
```bash
|
||||
yarn test <path/to/test>
|
||||
@@ -28,14 +28,14 @@ To debug the Cypress process under test, you can pass `--cypress-inspect-brk`:
|
||||
yarn test test/go_spec.js --browser chrome --no-exit
|
||||
```
|
||||
|
||||
## Developing tests
|
||||
## Developing Tests
|
||||
|
||||
System tests cover the entire Cypress run, so they are good for testing features that do not fit into a normal integration or unit test. However, they do take more resources to run, so consider carefully if you really *need* to write a system test, or if you could achieve 100% coverage via an integration or unit test instead.
|
||||
|
||||
There are two parts to a system test:
|
||||
|
||||
1. A test written using the [`systemTests`](./lib/system-tests) Mocha wrapper that lives in [`./test`](./test), and
|
||||
2. A matching Cypress project that lives in the [`./projects`](./projects) directory.
|
||||
2. A matching Cypress [test project](#Test-Projects) that lives in the [`./projects`](./projects) directory.
|
||||
|
||||
For example, if you initialized a new project in `./projects/my-new-project`, and you wanted to assert that 2 tests fail and take a snapshot of the `stdout`, you'd write a test like this:
|
||||
|
||||
@@ -61,10 +61,32 @@ From here, you could run this test with `yarn test my-new-project`.
|
||||
|
||||
There are many more options available for `systemTests.it` and `systemTests.setup`. You can massage the stdout, do pre-run tasks, set up HTTP/S servers, and more. Explore the typedocs in [`./lib/system-tests`](./lib/system-tests) for more information.
|
||||
|
||||
## Updating snaphots
|
||||
### Updating Snaphots
|
||||
|
||||
Prepend `SNAPSHOT_UPDATE=1` to any test command. See [`snap-shot-it` instructions](https://github.com/bahmutov/snap-shot-it#advanced-use) for more info.
|
||||
|
||||
```bash
|
||||
SNAPSHOT_UPDATE=1 yarn test go_spec
|
||||
```
|
||||
|
||||
### Test Projects
|
||||
|
||||
Every folder in [`./projects`](./lib/projects) represents a self-contained Cypress project. When you pass the `project` property to `systemTests.it` or `systemTests.exec`, Cypress launches using this project.
|
||||
|
||||
If a test project has a `package.json` file, the `systemTests.exec` helper will attempt to install the correct `node_modules` by running `yarn install` against the project. This is cached in CI and locally to speed up test times.
|
||||
|
||||
`systemTests.exec` *copies* the project directory to a temporary folder outside of the monorepo root. This means that temporary projects will not inherit the `node_modules` from this package or the monorepo. So, you must add the dependencies required for your project in `dependencies` or `devDependencies`.
|
||||
|
||||
The exception is some commonly used packages that are scaffolded for all projects, like `lodash` and `debug`. You can see the list by looking at `scaffoldCommonNodeModules` in [`./lib/fixtures.ts`](./lib/fixtures.ts) These packages do not need to be added to a test project's `package.json`.
|
||||
|
||||
You can also set special properties in a test project's `package.json` to influence the helper's behavior when running `yarn`:
|
||||
|
||||
`package.json` Property Name | Type | Description
|
||||
--- | --- | ---
|
||||
`_cySkipYarnInstall` | `boolean` | If `true`, skip the automatic `yarn install` for this package, even though it has a `package.json`.
|
||||
`_cyYarnV2` | `boolean` | Run the yarn v2-style install command instead of yarn v1-style.
|
||||
`_cyRunScripts` | `boolean` | By default, the automatic `yarn install` will not run postinstall scripts. This option, if set, will cause postinstall scripts to run for this project.
|
||||
|
||||
Run `yarn projects:yarn:install` to run `yarn install` for all projects with a `package.json`.
|
||||
|
||||
Use the `UPDATE_YARN_LOCK=1` environment variable with `yarn test` or `yarn projects:yarn:install` to allow the `yarn.lock` to be updated and synced back to the monorepo from the temp dir.
|
||||
@@ -25,6 +25,8 @@ Error: Webpack Compilation Error
|
||||
./cypress/support/index.js
|
||||
Module not found: Error: Can't resolve './does/not/exist' in '/foo/bar/.projects/busted-support-file/cypress/support'
|
||||
Looked for and couldn't find the file at the following paths:
|
||||
[/foo/bar/.projects/busted-support-file/cypress/support/package.json]
|
||||
[/foo/bar/.projects/busted-support-file/cypress/support/does/not/exist/package.json]
|
||||
[/foo/bar/.projects/busted-support-file/cypress/support/does/not/exist]
|
||||
[/foo/bar/.projects/busted-support-file/cypress/support/does/not/exist.js]
|
||||
[/foo/bar/.projects/busted-support-file/cypress/support/does/not/exist.json]
|
||||
|
||||
@@ -90,7 +90,7 @@ Error: Webpack Compilation Error
|
||||
./cypress/integration/typescript_syntax_error_spec.tsXX:XX
|
||||
Module parse failed: Unexpected token (3:19)
|
||||
File was processed with these loaders:
|
||||
* ../../../npm/webpack-batteries-included-preprocessor/node_modules/ts-loader/index.js
|
||||
* relative/path/to/webpack-batteries-included-preprocessor/node_modules/ts-loader/index.js
|
||||
You may need an additional loader to handle the result of these loaders.
|
||||
| // The code below is ignored by eslint
|
||||
| // because it tests failing spec.
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
const chokidar = require('chokidar')
|
||||
|
||||
const root = path.join(__dirname, '..')
|
||||
|
||||
const serverRoot = path.join(__dirname, '../../packages/server/')
|
||||
const projects = path.join(root, 'projects')
|
||||
const tmpDir = path.join(root, '.projects')
|
||||
|
||||
// copy contents instead of deleting+creating new file, which can cause
|
||||
// filewatchers to lose track of toFile.
|
||||
const copyContents = (fromFile, toFile) => {
|
||||
return Promise.all([
|
||||
fs.open(toFile, 'w'),
|
||||
fs.readFile(fromFile),
|
||||
])
|
||||
.then(([toFd, fromFileBuf]) => {
|
||||
return fs.write(toFd, fromFileBuf)
|
||||
.finally(() => {
|
||||
return fs.close(toFd)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
// copies all of the project fixtures
|
||||
// to the tmpDir .projects in the root
|
||||
scaffold () {
|
||||
return fs.copySync(projects, tmpDir)
|
||||
},
|
||||
|
||||
scaffoldWatch () {
|
||||
const watchdir = path.resolve(__dirname, '../projects')
|
||||
|
||||
console.log('watching files due to --no-exit', watchdir)
|
||||
|
||||
chokidar.watch(watchdir, {
|
||||
})
|
||||
.on('change', (srcFilepath, stats) => {
|
||||
const tmpFilepath = path.join(tmpDir, path.relative(watchdir, srcFilepath))
|
||||
|
||||
return copyContents(srcFilepath, tmpFilepath)
|
||||
})
|
||||
.on('error', console.error)
|
||||
},
|
||||
|
||||
// removes all of the project fixtures
|
||||
// from the tmpDir .projects in the root
|
||||
remove () {
|
||||
return fs.removeSync(tmpDir)
|
||||
},
|
||||
|
||||
async installStubPackage (projectPath, pkgName) {
|
||||
const pathToPkg = path.join(projectPath, 'node_modules', pkgName)
|
||||
|
||||
await fs.outputJSON(path.join(projectPath, 'package.json'), { name: 'some-project' })
|
||||
await fs.mkdirp(pathToPkg)
|
||||
await fs.outputFile(path.join(pathToPkg, 'index.js'), '')
|
||||
},
|
||||
|
||||
// returns the path to project fixture
|
||||
// in the tmpDir
|
||||
project (...args) {
|
||||
return this.projectPath.apply(this, args)
|
||||
},
|
||||
|
||||
projectPath (name) {
|
||||
return path.join(tmpDir, name)
|
||||
},
|
||||
|
||||
get (fixture, encoding = 'utf8') {
|
||||
return fs.readFileSync(path.join(serverRoot, 'test', 'support', 'fixtures', fixture), encoding)
|
||||
},
|
||||
|
||||
path (fixture) {
|
||||
return path.join(serverRoot, 'test', 'support', 'fixtures', fixture)
|
||||
},
|
||||
}
|
||||
346
system-tests/lib/fixtures.ts
Normal file
346
system-tests/lib/fixtures.ts
Normal file
@@ -0,0 +1,346 @@
|
||||
import fs from 'fs-extra'
|
||||
import _path from 'path'
|
||||
import chokidar from 'chokidar'
|
||||
import os from 'os'
|
||||
import cachedir from 'cachedir'
|
||||
import execa from 'execa'
|
||||
|
||||
const root = _path.join(__dirname, '..')
|
||||
|
||||
const serverRoot = _path.join(__dirname, '../../packages/server/')
|
||||
const projects = _path.join(root, 'projects')
|
||||
const tmpDir = _path.join(os.tmpdir(), 'cy-projects')
|
||||
|
||||
// copy contents instead of deleting+creating new file, which can cause
|
||||
// filewatchers to lose track of toFile.
|
||||
const copyContents = (fromFile, toFile) => {
|
||||
return Promise.all([
|
||||
fs.open(toFile, 'w'),
|
||||
fs.readFile(fromFile),
|
||||
])
|
||||
.then(([toFd, fromFileBuf]) => {
|
||||
return fs.write(toFd, fromFileBuf)
|
||||
.finally(() => {
|
||||
return fs.close(toFd)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// copies all of the project fixtures
|
||||
// to the tmpDir .projects in the root
|
||||
export function scaffold () {
|
||||
fs.copySync(projects, tmpDir)
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a project name, copy the project's test files to the temp dir.
|
||||
*/
|
||||
export function scaffoldProject (project: string): void {
|
||||
const from = _path.join(projects, project)
|
||||
const to = _path.join(tmpDir, project)
|
||||
|
||||
fs.copySync(from, to)
|
||||
}
|
||||
|
||||
/**
|
||||
* Symlink the cached `node_modules` directory to the temp project directory's `node_modules`.
|
||||
*/
|
||||
async function symlinkNodeModulesFromCache (project: string, cacheDir: string): Promise<void> {
|
||||
const from = _path.join(projectPath(project), 'node_modules')
|
||||
|
||||
try {
|
||||
await fs.stat(cacheDir)
|
||||
} catch (err) {
|
||||
console.log(`📦 Creating a new node_modules cache dir at ${cacheDir}`)
|
||||
await fs.mkdirp(cacheDir)
|
||||
}
|
||||
|
||||
try {
|
||||
await fs.symlink(cacheDir, from, 'junction')
|
||||
} catch (err) {
|
||||
if (err.code !== 'EEXIST') return
|
||||
}
|
||||
console.log(`📦 node_modules symlink created at ${from}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a package name, returns the path to the module directory on disk.
|
||||
*/
|
||||
function pathToPackage (pkg: string): string {
|
||||
return _path.dirname(require.resolve(`${pkg}/package.json`))
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a path to a `package.json`, convert any references to development
|
||||
* versions of packages to absolute paths, so `yarn` will not reach out to
|
||||
* the Internet to obtain these packages once it runs in the temp dir.
|
||||
* @returns a list of dependency names that were updated
|
||||
*/
|
||||
async function makeWorkspacePackagesAbsolute (pathToPkgJson: string): Promise<string[]> {
|
||||
const pkgJson = await fs.readJson(pathToPkgJson)
|
||||
const updatedDeps: string[] = []
|
||||
|
||||
for (const deps of [pkgJson.dependencies, pkgJson.devDependencies, pkgJson.optionalDependencies]) {
|
||||
for (const dep in deps) {
|
||||
const version = deps[dep]
|
||||
|
||||
if (version.startsWith('file:')) {
|
||||
const absPath = pathToPackage(dep)
|
||||
|
||||
console.log(`📦 Setting absolute path in package.json for ${dep}: ${absPath}.`)
|
||||
|
||||
deps[dep] = `file:${absPath}`
|
||||
updatedDeps.push(dep)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await fs.writeJson(pathToPkgJson, pkgJson)
|
||||
|
||||
return updatedDeps
|
||||
}
|
||||
|
||||
function getYarnCommand (opts: {
|
||||
yarnV2: boolean
|
||||
updateYarnLock: boolean
|
||||
isCI: boolean
|
||||
runScripts: boolean
|
||||
}): string {
|
||||
let cmd = `yarn install`
|
||||
|
||||
if (opts.yarnV2) {
|
||||
// yarn v2's docs are no longer available on their site now that yarn v3 is out,
|
||||
// Internet Archive has them here:
|
||||
// @see https://web.archive.org/web/20210102223647/https://yarnpkg.com/cli/install
|
||||
if (!opts.runScripts) cmd += ' --skip-builds'
|
||||
|
||||
if (!opts.updateYarnLock) cmd += ' --immutable'
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
cmd += ' --prefer-offline'
|
||||
|
||||
if (!opts.runScripts) cmd += ' --ignore-scripts'
|
||||
|
||||
if (!opts.updateYarnLock) cmd += ' --frozen-lockfile'
|
||||
|
||||
// yarn v1 has a bug with integrity checking and local cache/dependencies
|
||||
// @see https://github.com/yarnpkg/yarn/issues/6407
|
||||
cmd += ' --update-checksums'
|
||||
|
||||
// in CircleCI, this offline cache can be used
|
||||
if (opts.isCI) cmd += ` --cache-folder=~/.yarn-${process.platform} `
|
||||
else cmd += ` --cache-folder=${_path.join(os.tmpdir(), 'cy-system-tests-yarn-cache', String(Date.now()))}`
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
type Dependencies = Record<string, string>
|
||||
|
||||
/**
|
||||
* Type for package.json files for system-tests example projects.
|
||||
*/
|
||||
type SystemTestPkgJson = {
|
||||
/**
|
||||
* By default, scaffolding will run `yarn install` if there is a `package.json`.
|
||||
* This option, if set, disables that.
|
||||
*/
|
||||
_cySkipYarnInstall?: boolean
|
||||
/**
|
||||
* Run the yarn v2-style install command instead of yarn v1-style.
|
||||
*/
|
||||
_cyYarnV2?: boolean
|
||||
/**
|
||||
* By default, the automatic `yarn install` will not run postinstall scripts. This
|
||||
* option, if set, will cause postinstall scripts to run for this project.
|
||||
*/
|
||||
_cyRunScripts?: boolean
|
||||
dependencies?: Dependencies
|
||||
devDependencies?: Dependencies
|
||||
optionalDependencies?: Dependencies
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a `system-tests` project name, detect and install the `node_modules`
|
||||
* specified in the project's `package.json`. No-op if no `package.json` is found.
|
||||
*/
|
||||
export async function scaffoldProjectNodeModules (project: string, updateYarnLock: boolean = !!process.env.UPDATE_YARN_LOCK): Promise<void> {
|
||||
const projectDir = projectPath(project)
|
||||
const relativePathToMonorepoRoot = _path.relative(
|
||||
_path.join(projects, project),
|
||||
_path.join(root, '..'),
|
||||
)
|
||||
const projectPkgJsonPath = _path.join(projectDir, 'package.json')
|
||||
|
||||
const runCmd = async (cmd) => {
|
||||
console.log(`📦 Running "${cmd}" in ${projectDir}`)
|
||||
await execa.shell(cmd, { cwd: projectDir, stdio: 'inherit' })
|
||||
}
|
||||
|
||||
const cacheDir = _path.join(cachedir('cy-system-tests-node-modules'), project, 'node_modules')
|
||||
|
||||
async function removeWorkspacePackages (packages: string[]): Promise<void> {
|
||||
for (const dep of packages) {
|
||||
const depDir = _path.join(cacheDir, dep)
|
||||
|
||||
await fs.remove(depDir)
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// this will throw and exit early if the package.json does not exist
|
||||
const pkgJson: SystemTestPkgJson = require(projectPkgJsonPath)
|
||||
|
||||
console.log(`📦 Found package.json for project ${project}.`)
|
||||
|
||||
if (pkgJson._cySkipYarnInstall) {
|
||||
return console.log(`📦 cySkipYarnInstall set in package.json, skipping yarn steps`)
|
||||
}
|
||||
|
||||
if (!pkgJson.dependencies && !pkgJson.devDependencies && !pkgJson.optionalDependencies) {
|
||||
return console.log(`📦 No dependencies found, skipping yarn steps`)
|
||||
}
|
||||
|
||||
// 1. Ensure there is a cache directory set up for this test project's `node_modules`.
|
||||
await symlinkNodeModulesFromCache(project, cacheDir)
|
||||
|
||||
// 2. Before running `yarn`, resolve workspace deps to absolute paths.
|
||||
// This is required to fix `yarn install` for workspace-only packages.
|
||||
const workspaceDeps = await makeWorkspacePackagesAbsolute(projectPkgJsonPath)
|
||||
|
||||
await removeWorkspacePackages(workspaceDeps)
|
||||
|
||||
// 3. Fix relative paths in temp dir's `yarn.lock`.
|
||||
const relativePathToProjectDir = _path.relative(projectDir, _path.join(root, '..'))
|
||||
const yarnLockPath = _path.join(projectDir, 'yarn.lock')
|
||||
|
||||
console.log('📦 Writing yarn.lock with fixed relative paths to temp dir')
|
||||
try {
|
||||
const yarnLock = (await fs.readFile(yarnLockPath, 'utf8'))
|
||||
.replaceAll(relativePathToMonorepoRoot, relativePathToProjectDir)
|
||||
|
||||
await fs.writeFile(yarnLockPath, yarnLock)
|
||||
} catch (err) {
|
||||
if (err.code !== 'ENOENT' || !updateYarnLock) throw err
|
||||
|
||||
console.log('📦 No yarn.lock found, continuing')
|
||||
}
|
||||
|
||||
// 4. Run `yarn install`.
|
||||
const cmd = getYarnCommand({
|
||||
updateYarnLock,
|
||||
yarnV2: pkgJson._cyYarnV2,
|
||||
isCI: !!process.env.CI,
|
||||
runScripts: pkgJson._cyRunScripts,
|
||||
})
|
||||
|
||||
await runCmd(cmd)
|
||||
|
||||
console.log(`📦 Copying yarn.lock and fixing relative paths for ${project}`)
|
||||
|
||||
// Replace workspace dependency paths in `yarn.lock` with tokens so it can be the same
|
||||
// for all developers
|
||||
const yarnLock = (await fs.readFile(yarnLockPath, 'utf8'))
|
||||
.replaceAll(relativePathToProjectDir, relativePathToMonorepoRoot)
|
||||
|
||||
await fs.writeFile(_path.join(projects, project, 'yarn.lock'), yarnLock)
|
||||
|
||||
// 5. After `yarn install`, we must now symlink *over* all workspace dependencies, or else
|
||||
// `require` calls from `yarn install`'d workspace deps to peer deps will fail.
|
||||
await removeWorkspacePackages(workspaceDeps)
|
||||
for (const dep of workspaceDeps) {
|
||||
console.log(`📦 Symlinking workspace dependency: ${dep}`)
|
||||
const depDir = _path.join(cacheDir, dep)
|
||||
|
||||
await fs.symlink(pathToPackage(dep), depDir, 'junction')
|
||||
}
|
||||
} catch (err) {
|
||||
if (err.code === 'MODULE_NOT_FOUND') return
|
||||
|
||||
console.error(`⚠ An error occurred while installing the node_modules for ${project}.`)
|
||||
console.error([err.message, err.stack].join('\n'))
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
export async function scaffoldCommonNodeModules () {
|
||||
await Promise.all([
|
||||
'@cypress/code-coverage',
|
||||
'@cypress/webpack-dev-server',
|
||||
'@packages/socket',
|
||||
'@packages/ts',
|
||||
'@tooling/system-tests',
|
||||
'bluebird',
|
||||
'chai',
|
||||
'dayjs',
|
||||
'debug',
|
||||
'execa',
|
||||
'fs-extra',
|
||||
'https-proxy-agent',
|
||||
'jimp',
|
||||
'lazy-ass',
|
||||
'lodash',
|
||||
'proxyquire',
|
||||
'react',
|
||||
'semver',
|
||||
'systeminformation',
|
||||
'tslib',
|
||||
'typescript',
|
||||
].map(symlinkNodeModule))
|
||||
}
|
||||
|
||||
export async function symlinkNodeModule (pkg) {
|
||||
const from = _path.join(tmpDir, 'node_modules', pkg)
|
||||
const to = pathToPackage(pkg)
|
||||
|
||||
await fs.ensureDir(_path.dirname(from))
|
||||
try {
|
||||
await fs.symlink(to, from, 'junction')
|
||||
} catch (err) {
|
||||
if (err.code === 'EEXIST') return
|
||||
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
export function scaffoldWatch () {
|
||||
const watchdir = _path.resolve(__dirname, '../projects')
|
||||
|
||||
console.log('watching files due to --no-exit', watchdir)
|
||||
|
||||
chokidar.watch(watchdir, {
|
||||
})
|
||||
.on('change', (srcFilepath, stats) => {
|
||||
const tmpFilepath = _path.join(tmpDir, _path.relative(watchdir, srcFilepath))
|
||||
|
||||
return copyContents(srcFilepath, tmpFilepath)
|
||||
})
|
||||
.on('error', console.error)
|
||||
}
|
||||
|
||||
// removes all of the project fixtures
|
||||
// from the tmpDir .projects in the root
|
||||
export function remove () {
|
||||
return fs.removeSync(tmpDir)
|
||||
}
|
||||
|
||||
// returns the path to project fixture
|
||||
// in the tmpDir
|
||||
export function project (...args) {
|
||||
return this.projectPath.apply(this, args)
|
||||
}
|
||||
|
||||
export function projectPath (name) {
|
||||
return _path.join(tmpDir, name)
|
||||
}
|
||||
|
||||
export function get (fixture, encoding: BufferEncoding = 'utf8') {
|
||||
return fs.readFileSync(_path.join(serverRoot, 'test', 'support', 'fixtures', fixture), { encoding })
|
||||
}
|
||||
|
||||
export function path (fixture) {
|
||||
return _path.join(serverRoot, 'test', 'support', 'fixtures', fixture)
|
||||
}
|
||||
|
||||
export default module.exports
|
||||
@@ -200,9 +200,9 @@ type ExecOptions = {
|
||||
*/
|
||||
noTypeScript?: boolean
|
||||
/**
|
||||
* If set, a dummy `node_modules` project with this name will be set up.
|
||||
* Skip scaffolding the project and node_modules.
|
||||
*/
|
||||
stubPackage?: string
|
||||
skipScaffold?: boolean
|
||||
/**
|
||||
* Run Cypress with a custom user node path.
|
||||
*/
|
||||
@@ -475,12 +475,8 @@ const startServer = function (obj) {
|
||||
app.use(require('cors')())
|
||||
}
|
||||
|
||||
const s = obj.static
|
||||
|
||||
if (s) {
|
||||
const opts = _.isObject(s) ? s : {}
|
||||
|
||||
app.use(express.static(e2ePath, opts))
|
||||
if (obj.static) {
|
||||
app.use(express.static(path.join(__dirname, '../projects/e2e'), {}))
|
||||
}
|
||||
|
||||
return new Bluebird((resolve) => {
|
||||
@@ -670,17 +666,16 @@ const systemTests = {
|
||||
|
||||
setup (options: SetupOptions = {}) {
|
||||
beforeEach(async function () {
|
||||
// after installing node modules copying all of the fixtures
|
||||
// can take a long time (5-15 secs)
|
||||
this.timeout(human('2 minutes'))
|
||||
Fixtures.scaffold()
|
||||
// // after installing node modules copying all of the fixtures
|
||||
// // can take a long time (5-15 secs)
|
||||
// this.timeout(human('2 minutes'))
|
||||
|
||||
if (process.env.NO_EXIT) {
|
||||
Fixtures.scaffoldWatch()
|
||||
}
|
||||
Fixtures.remove()
|
||||
|
||||
sinon.stub(process, 'exit')
|
||||
|
||||
this.settings = options.settings
|
||||
|
||||
if (options.servers) {
|
||||
const optsServers = [].concat(options.servers)
|
||||
|
||||
@@ -690,12 +685,6 @@ const systemTests = {
|
||||
} else {
|
||||
this.servers = null
|
||||
}
|
||||
|
||||
const s = options.settings
|
||||
|
||||
if (s) {
|
||||
await settings.write(e2ePath, s)
|
||||
}
|
||||
})
|
||||
|
||||
afterEach(async function () {
|
||||
@@ -703,8 +692,6 @@ const systemTests = {
|
||||
|
||||
this.timeout(human('2 minutes'))
|
||||
|
||||
Fixtures.remove()
|
||||
|
||||
const s = this.servers
|
||||
|
||||
if (s) {
|
||||
@@ -725,7 +712,7 @@ const systemTests = {
|
||||
_.defaults(options, {
|
||||
browser: 'electron',
|
||||
headed: process.env.HEADED || false,
|
||||
project: e2ePath,
|
||||
project: 'e2e',
|
||||
timeout: 120000,
|
||||
originalTitle: null,
|
||||
expectedExitCode: 0,
|
||||
@@ -735,6 +722,8 @@ const systemTests = {
|
||||
inspectBrk: process.env.CYPRESS_INSPECT_BRK,
|
||||
})
|
||||
|
||||
const projectPath = Fixtures.projectPath(options.project)
|
||||
|
||||
if (options.exit != null) {
|
||||
throw new Error(`
|
||||
passing { exit: false } to system test options is no longer supported
|
||||
@@ -760,7 +749,7 @@ const systemTests = {
|
||||
|
||||
const specDir = options.testingType === 'component' ? 'component' : 'integration'
|
||||
|
||||
return path.join(options.project, 'cypress', specDir, spec)
|
||||
return path.join(projectPath, 'cypress', specDir, spec)
|
||||
})
|
||||
|
||||
// normalize the path to the spec
|
||||
@@ -776,7 +765,7 @@ const systemTests = {
|
||||
const args = [
|
||||
// hides a user warning to go through NPM module
|
||||
`--cwd=${serverPath}`,
|
||||
`--run-project=${options.project}`,
|
||||
`--run-project=${Fixtures.projectPath(options.project)}`,
|
||||
`--testingType=${options.testingType || 'e2e'}`,
|
||||
]
|
||||
|
||||
@@ -902,7 +891,7 @@ const systemTests = {
|
||||
console.log(systemTests.normalizeStdout(result.stdout))
|
||||
```
|
||||
*/
|
||||
exec (ctx, options: ExecOptions) {
|
||||
async exec (ctx, options: ExecOptions) {
|
||||
debug('systemTests.exec options %o', options)
|
||||
options = this.options(ctx, options)
|
||||
debug('processed options %o', options)
|
||||
@@ -914,8 +903,18 @@ const systemTests = {
|
||||
ctx.skip()
|
||||
}
|
||||
|
||||
if (options.stubPackage) {
|
||||
Fixtures.installStubPackage(options.project, options.stubPackage)
|
||||
if (!options.skipScaffold) {
|
||||
await Fixtures.scaffoldCommonNodeModules()
|
||||
Fixtures.scaffoldProject(options.project)
|
||||
await Fixtures.scaffoldProjectNodeModules(options.project)
|
||||
}
|
||||
|
||||
if (process.env.NO_EXIT) {
|
||||
Fixtures.scaffoldWatch()
|
||||
}
|
||||
|
||||
if (ctx.settings) {
|
||||
await settings.write(e2ePath, ctx.settings)
|
||||
}
|
||||
|
||||
args = options.args || ['index.js'].concat(args)
|
||||
@@ -994,70 +993,73 @@ const systemTests = {
|
||||
}
|
||||
}
|
||||
|
||||
return new Bluebird((resolve, reject) => {
|
||||
debug('spawning Cypress %o', { args })
|
||||
const cmd = options.command || 'node'
|
||||
const sp = cp.spawn(cmd, args, {
|
||||
env: _.chain(process.env)
|
||||
.omit('CYPRESS_DEBUG')
|
||||
.extend({
|
||||
// FYI: color will be disabled
|
||||
// because we are piping the child process
|
||||
COLUMNS: 100,
|
||||
LINES: 24,
|
||||
})
|
||||
.defaults({
|
||||
// match CircleCI's filesystem limits, so screenshot names in snapshots match
|
||||
CYPRESS_MAX_SAFE_FILENAME_BYTES: 242,
|
||||
FAKE_CWD_PATH: '/XXX/XXX/XXX',
|
||||
DEBUG_COLORS: '1',
|
||||
// prevent any Compression progress
|
||||
// messages from showing up
|
||||
VIDEO_COMPRESSION_THROTTLE: 120000,
|
||||
|
||||
// don't fail our own tests running from forked PR's
|
||||
CYPRESS_INTERNAL_SYSTEM_TESTS: '1',
|
||||
|
||||
// Emulate no typescript environment
|
||||
CYPRESS_INTERNAL_NO_TYPESCRIPT: options.noTypeScript ? '1' : '0',
|
||||
|
||||
// disable frame skipping to make quick Chromium tests have matching snapshots/working video
|
||||
CYPRESS_EVERY_NTH_FRAME: 1,
|
||||
|
||||
// force file watching for use with --no-exit
|
||||
...(options.noExit ? { CYPRESS_INTERNAL_FORCE_FILEWATCH: '1' } : {}),
|
||||
})
|
||||
.extend(options.processEnv)
|
||||
.value(),
|
||||
...options.spawnOpts,
|
||||
debug('spawning Cypress %o', { args })
|
||||
const cmd = options.command || 'node'
|
||||
const sp = cp.spawn(cmd, args, {
|
||||
env: _.chain(process.env)
|
||||
.omit('CYPRESS_DEBUG')
|
||||
.extend({
|
||||
// FYI: color will be disabled
|
||||
// because we are piping the child process
|
||||
COLUMNS: 100,
|
||||
LINES: 24,
|
||||
})
|
||||
.defaults({
|
||||
// match CircleCI's filesystem limits, so screenshot names in snapshots match
|
||||
CYPRESS_MAX_SAFE_FILENAME_BYTES: 242,
|
||||
FAKE_CWD_PATH: '/XXX/XXX/XXX',
|
||||
DEBUG_COLORS: '1',
|
||||
// prevent any Compression progress
|
||||
// messages from showing up
|
||||
VIDEO_COMPRESSION_THROTTLE: 120000,
|
||||
|
||||
const ColorOutput = function () {
|
||||
const colorOutput = new stream.Transform()
|
||||
// don't fail our own tests running from forked PR's
|
||||
CYPRESS_INTERNAL_SYSTEM_TESTS: '1',
|
||||
|
||||
colorOutput._transform = (chunk, encoding, cb) => cb(null, chalk.magenta(chunk.toString()))
|
||||
// Emulate no typescript environment
|
||||
CYPRESS_INTERNAL_NO_TYPESCRIPT: options.noTypeScript ? '1' : '0',
|
||||
|
||||
return colorOutput
|
||||
}
|
||||
// disable frame skipping to make quick Chromium tests have matching snapshots/working video
|
||||
CYPRESS_EVERY_NTH_FRAME: 1,
|
||||
|
||||
// pipe these to our current process
|
||||
// so we can see them in the terminal
|
||||
// color it so we can tell which is test output
|
||||
sp.stdout
|
||||
.pipe(ColorOutput())
|
||||
.pipe(process.stdout)
|
||||
// force file watching for use with --no-exit
|
||||
...(options.noExit ? { CYPRESS_INTERNAL_FORCE_FILEWATCH: '1' } : {}),
|
||||
})
|
||||
.extend(options.processEnv)
|
||||
.value(),
|
||||
...options.spawnOpts,
|
||||
})
|
||||
|
||||
sp.stderr
|
||||
.pipe(ColorOutput())
|
||||
.pipe(process.stderr)
|
||||
const ColorOutput = function () {
|
||||
const colorOutput = new stream.Transform()
|
||||
|
||||
sp.stdout.on('data', (buf) => stdout += buf.toString())
|
||||
sp.stderr.on('data', (buf) => stderr += buf.toString())
|
||||
colorOutput._transform = (chunk, encoding, cb) => cb(null, chalk.magenta(chunk.toString()))
|
||||
|
||||
return colorOutput
|
||||
}
|
||||
|
||||
// pipe these to our current process
|
||||
// so we can see them in the terminal
|
||||
// color it so we can tell which is test output
|
||||
sp.stdout
|
||||
.pipe(ColorOutput())
|
||||
.pipe(process.stdout)
|
||||
|
||||
sp.stderr
|
||||
.pipe(ColorOutput())
|
||||
.pipe(process.stderr)
|
||||
|
||||
sp.stdout.on('data', (buf) => stdout += buf.toString())
|
||||
sp.stderr.on('data', (buf) => stderr += buf.toString())
|
||||
|
||||
const exitCode = await new Promise((resolve, reject) => {
|
||||
sp.on('error', reject)
|
||||
sp.on('exit', resolve)
|
||||
})
|
||||
|
||||
return sp.on('exit', resolve)
|
||||
}).tap(copy)
|
||||
.then(exit)
|
||||
await copy()
|
||||
|
||||
return exit(exitCode)
|
||||
},
|
||||
|
||||
sendHtml (contents) {
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"private": true,
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"projects:yarn:install": "node ./scripts/projects-yarn-install.js",
|
||||
"test": "node ./scripts/run.js --glob-in-dir=test",
|
||||
"test:ci": "node ./scripts/run.js"
|
||||
},
|
||||
@@ -29,6 +30,7 @@
|
||||
"babel-loader": "8.1.0",
|
||||
"bluebird": "3.7.2",
|
||||
"body-parser": "1.19.0",
|
||||
"cachedir": "2.3.0",
|
||||
"chai": "1.10.0",
|
||||
"chai-as-promised": "7.1.1",
|
||||
"chai-subset": "1.6.0",
|
||||
@@ -47,6 +49,7 @@
|
||||
"express-useragent": "1.0.15",
|
||||
"fluent-ffmpeg": "2.1.2",
|
||||
"fs-extra": "8.1.0",
|
||||
"glob": "7.2.0",
|
||||
"http-mitm-proxy": "0.7.0",
|
||||
"https-proxy-agent": "3.0.1",
|
||||
"human-interval": "1.0.0",
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "@test-projects/config-with-custom-file-js",
|
||||
"version": "0.0.0-test",
|
||||
"devDependencies": {
|
||||
"cypress": "file:../../../cli"
|
||||
}
|
||||
}
|
||||
1141
system-tests/projects/config-with-custom-file-js/yarn.lock
Normal file
1141
system-tests/projects/config-with-custom-file-js/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@ const _ = require('lodash')
|
||||
const Jimp = require('jimp')
|
||||
const path = require('path')
|
||||
const Promise = require('bluebird')
|
||||
const { useFixedBrowserLaunchSize } = require('../../../utils')
|
||||
const { useFixedBrowserLaunchSize } = require('@tooling/system-tests/lib/pluginUtils')
|
||||
|
||||
const { startDevServer } = require('@cypress/webpack-dev-server')
|
||||
|
||||
|
||||
7
system-tests/projects/plugin-retries/package.json
Normal file
7
system-tests/projects/plugin-retries/package.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "@test-project/plugin-retries",
|
||||
"version": "0.0.0-test",
|
||||
"devDependencies": {
|
||||
"cypress-plugin-retries": "1.5.2"
|
||||
}
|
||||
}
|
||||
49
system-tests/projects/plugin-retries/yarn.lock
Normal file
49
system-tests/projects/plugin-retries/yarn.lock
Normal file
@@ -0,0 +1,49 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
ansi-styles@^4.1.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
|
||||
integrity "sha1-7dgDYornHATIWuegkG7a00tkiTc= sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="
|
||||
dependencies:
|
||||
color-convert "^2.0.1"
|
||||
|
||||
chalk@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4"
|
||||
integrity "sha1-P3PCv1JlkfV0zEksUeJFY0n4ROQ= sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg=="
|
||||
dependencies:
|
||||
ansi-styles "^4.1.0"
|
||||
supports-color "^7.1.0"
|
||||
|
||||
color-convert@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
|
||||
integrity "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM= sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="
|
||||
dependencies:
|
||||
color-name "~1.1.4"
|
||||
|
||||
color-name@~1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
||||
integrity "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI= sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
|
||||
cypress-plugin-retries@1.5.2:
|
||||
version "1.5.2"
|
||||
resolved "https://registry.npmjs.org/cypress-plugin-retries/-/cypress-plugin-retries-1.5.2.tgz#21d5247cd77013b95bbfdd914f2de66f91f76a2e"
|
||||
integrity "sha1-IdUkfNdwE7lbv92RTy3mb5H3ai4= sha512-o1xVIGtv4WvNVxoVJ2X08eAuvditPHrePRzHqhwwHbMKu3C2rtxCdanRCZdO5fjh8ww+q4v4V0e9GmysbOvu3A=="
|
||||
dependencies:
|
||||
chalk "^3.0.0"
|
||||
|
||||
has-flag@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
|
||||
integrity "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s= sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
|
||||
|
||||
supports-color@^7.1.0:
|
||||
version "7.2.0"
|
||||
resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
|
||||
integrity "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo= sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="
|
||||
dependencies:
|
||||
has-flag "^4.0.0"
|
||||
@@ -1,6 +1,6 @@
|
||||
/// <reference types="cypress" />
|
||||
|
||||
const { useFixedBrowserLaunchSize } = require('../../../utils')
|
||||
const { useFixedBrowserLaunchSize } = require('@tooling/system-tests/lib/pluginUtils')
|
||||
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "@test-project/webpack-preprocessor-ts-loader-compiler-options",
|
||||
"version": "0.0.0-test",
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.9.0",
|
||||
"@babel/preset-env": "7.9.0",
|
||||
"@cypress/webpack-preprocessor": "file:../../../npm/webpack-preprocessor",
|
||||
"babel-loader": "8.1.0",
|
||||
"cypress": "file:../../../cli",
|
||||
"ts-loader": "7.0.4",
|
||||
"typescript": "4.2.3"
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "@test-project/webpack-preprocessor-ts-loader",
|
||||
"version": "0.0.0-test",
|
||||
"devDependencies": {
|
||||
"@cypress/webpack-preprocessor": "file:../../../npm/webpack-preprocessor",
|
||||
"cypress": "file:../../../cli/build",
|
||||
"ts-loader": "7.0.4",
|
||||
"typescript": "4.2.3"
|
||||
}
|
||||
}
|
||||
1363
system-tests/projects/webpack-preprocessor-ts-loader/yarn.lock
Normal file
1363
system-tests/projects/webpack-preprocessor-ts-loader/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
10
system-tests/projects/webpack-preprocessor/package.json
Normal file
10
system-tests/projects/webpack-preprocessor/package.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "@test-project/webpack-preprocessor",
|
||||
"version": "0.0.0-test",
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.9.0",
|
||||
"@babel/preset-env": "7.9.0",
|
||||
"@cypress/webpack-preprocessor": "file:../../../npm/webpack-preprocessor",
|
||||
"babel-loader": "8.1.0"
|
||||
}
|
||||
}
|
||||
1279
system-tests/projects/webpack-preprocessor/yarn.lock
Normal file
1279
system-tests/projects/webpack-preprocessor/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
@@ -7,5 +7,6 @@
|
||||
"devDependencies": {
|
||||
"typescript": "^4.2.4"
|
||||
},
|
||||
"license": "MIT"
|
||||
"license": "MIT",
|
||||
"_cyYarnV2": true
|
||||
}
|
||||
|
||||
8
system-tests/scripts/cache-key.sh
Executable file
8
system-tests/scripts/cache-key.sh
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
# NOTE: do not wrap this script with `yarn run`, `npm run`, etc., they add their own stdout
|
||||
|
||||
# cd to this "scripts" directory
|
||||
cd "$(dirname "${BASH_SOURCE[0]}")"
|
||||
|
||||
cat ../projects/**/{package.json,yarn.lock}
|
||||
37
system-tests/scripts/projects-yarn-install.js
Normal file
37
system-tests/scripts/projects-yarn-install.js
Normal file
@@ -0,0 +1,37 @@
|
||||
require('@packages/ts/register')
|
||||
const path = require('path')
|
||||
const { promisify } = require('util')
|
||||
const glob = promisify(require('glob'))
|
||||
const Fixtures = require('../lib/fixtures')
|
||||
|
||||
const logTag = '[update-cache.js]'
|
||||
const log = (...args) => console.log(logTag, ...args)
|
||||
|
||||
;(async () => {
|
||||
/**
|
||||
* For all system test projects that have a package.json, check and update
|
||||
* the node_modules cache using `yarn`.
|
||||
*/
|
||||
Fixtures.remove()
|
||||
|
||||
const projectsDir = path.join(__dirname, '../projects')
|
||||
const packageJsons = await glob('**/package.json', {
|
||||
cwd: projectsDir,
|
||||
})
|
||||
|
||||
log('Found', packageJsons.length, '`package.json` files in `projects`:', packageJsons)
|
||||
|
||||
for (const packageJsonPath of packageJsons) {
|
||||
const project = path.dirname(packageJsonPath)
|
||||
const timeTag = `${logTag} ${project} node_modules install`
|
||||
|
||||
console.time(timeTag)
|
||||
log('Scaffolding node_modules for', project)
|
||||
|
||||
Fixtures.scaffoldProject(project)
|
||||
await Fixtures.scaffoldProjectNodeModules(project)
|
||||
console.timeEnd(timeTag)
|
||||
}
|
||||
|
||||
log('Updated node_modules for', packageJsons.length, 'projects.')
|
||||
})()
|
||||
@@ -1,5 +1,5 @@
|
||||
import systemTests from '../lib/system-tests'
|
||||
import Fixtures from '../lib/fixtures'
|
||||
import systemTests from '../lib/system-tests'
|
||||
import browserUtils from '@packages/server/lib/browsers/utils'
|
||||
|
||||
const browser = {
|
||||
@@ -20,7 +20,7 @@ describe('e2e before:browser:launch', () => {
|
||||
PATH_TO_CHROME_PROFILE,
|
||||
},
|
||||
},
|
||||
project: Fixtures.projectPath('chrome-browser-preferences'),
|
||||
project: 'chrome-browser-preferences',
|
||||
snapshot: true,
|
||||
spec: 'spec.js',
|
||||
})
|
||||
@@ -31,8 +31,12 @@ describe('e2e before:browser:launch', () => {
|
||||
video: false,
|
||||
},
|
||||
headed: true,
|
||||
project: Fixtures.projectPath('browser-extensions'),
|
||||
project: 'browser-extensions',
|
||||
sanitizeScreenshotDimensions: true,
|
||||
snapshot: true,
|
||||
onRun: async (exec) => {
|
||||
Fixtures.scaffoldProject('plugin-extension')
|
||||
await exec()
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
@@ -2,7 +2,6 @@ const path = require('path')
|
||||
const { exec } = require('child_process')
|
||||
|
||||
const systemTests = require('../lib/system-tests').default
|
||||
const Fixtures = require('../lib/fixtures')
|
||||
const launcher = require('@packages/launcher')
|
||||
|
||||
const absPath = (pathStr) => {
|
||||
@@ -26,7 +25,7 @@ describe('e2e launching browsers by path', () => {
|
||||
|
||||
it('fails with bad browser path', function () {
|
||||
return systemTests.exec(this, {
|
||||
project: Fixtures.projectPath('e2e'),
|
||||
project: 'e2e',
|
||||
spec: 'simple_spec.js',
|
||||
browser: '/this/aint/gonna/be/found',
|
||||
expectedExitCode: 1,
|
||||
@@ -53,7 +52,7 @@ describe('e2e launching browsers by path', () => {
|
||||
.then((absPath))
|
||||
.then((foundPath) => {
|
||||
return systemTests.exec(this, {
|
||||
project: Fixtures.projectPath('e2e'),
|
||||
project: 'e2e',
|
||||
spec: 'simple_spec.js',
|
||||
browser: foundPath,
|
||||
snapshot: true,
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
const Fixtures = require('../lib/fixtures')
|
||||
const systemTests = require('../lib/system-tests').default
|
||||
|
||||
const bustedSupportFile = Fixtures.projectPath('busted-support-file')
|
||||
|
||||
describe('e2e busted support file', () => {
|
||||
systemTests.setup()
|
||||
|
||||
it('passes', function () {
|
||||
return systemTests.exec(this, {
|
||||
project: bustedSupportFile,
|
||||
project: 'busted-support-file',
|
||||
sanitizeScreenshotDimensions: true,
|
||||
snapshot: true,
|
||||
expectedExitCode: 1,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
const express = require('express')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const Fixtures = require('../lib/fixtures')
|
||||
@@ -10,6 +11,11 @@ const e2ePath = Fixtures.projectPath('e2e')
|
||||
let requestsForCache = 0
|
||||
|
||||
const onServer = function (app) {
|
||||
app.use(express.static(e2ePath, {
|
||||
// force caching to happen
|
||||
maxAge: 3600000,
|
||||
}))
|
||||
|
||||
app.post('/write/:text', (req, res) => {
|
||||
const file = path.join(e2ePath, 'index.html')
|
||||
|
||||
@@ -23,7 +29,7 @@ const onServer = function (app) {
|
||||
})
|
||||
})
|
||||
|
||||
return app.get('/cached', (req, res) => {
|
||||
app.get('/cached', (req, res) => {
|
||||
requestsForCache += 1
|
||||
|
||||
return res
|
||||
@@ -37,10 +43,6 @@ describe('e2e cache', () => {
|
||||
servers: {
|
||||
port: 1515,
|
||||
onServer,
|
||||
static: {
|
||||
// force caching to happen
|
||||
maxAge: 3600000,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import mockedEnv from 'mocked-env'
|
||||
import systemTests from '../lib/system-tests'
|
||||
import Fixtures from '../lib/fixtures'
|
||||
|
||||
describe('e2e cdp', function () {
|
||||
systemTests.setup()
|
||||
@@ -18,7 +17,7 @@ describe('e2e cdp', function () {
|
||||
|
||||
// NOTE: this test takes almost a minute and is largely redundant with protocol_spec
|
||||
systemTests.it.skip('fails when remote debugging port cannot be connected to', {
|
||||
project: Fixtures.projectPath('remote-debugging-port-removed'),
|
||||
project: 'remote-debugging-port-removed',
|
||||
spec: 'spec.ts',
|
||||
browser: 'chrome',
|
||||
expectedExitCode: 1,
|
||||
@@ -26,7 +25,7 @@ describe('e2e cdp', function () {
|
||||
|
||||
// https://github.com/cypress-io/cypress/issues/5685
|
||||
systemTests.it('handles disconnections as expected', {
|
||||
project: Fixtures.projectPath('remote-debugging-disconnect'),
|
||||
project: 'remote-debugging-disconnect',
|
||||
spec: 'spec.ts',
|
||||
browser: 'chrome',
|
||||
expectedExitCode: 1,
|
||||
|
||||
@@ -20,7 +20,7 @@ describe('e2e config', () => {
|
||||
|
||||
it('applies defaultCommandTimeout globally', function () {
|
||||
return systemTests.exec(this, {
|
||||
project: Fixtures.projectPath('config-with-short-timeout'),
|
||||
project: 'config-with-short-timeout',
|
||||
snapshot: true,
|
||||
expectedExitCode: 1,
|
||||
})
|
||||
@@ -30,7 +30,7 @@ describe('e2e config', () => {
|
||||
|
||||
it('throws error when invalid viewportWidth in the configuration file', function () {
|
||||
return systemTests.exec(this, {
|
||||
project: Fixtures.projectPath('config-with-invalid-viewport'),
|
||||
project: 'config-with-invalid-viewport',
|
||||
expectedExitCode: 1,
|
||||
snapshot: true,
|
||||
})
|
||||
@@ -38,7 +38,7 @@ describe('e2e config', () => {
|
||||
|
||||
it('throws error when invalid browser in the configuration file', function () {
|
||||
return systemTests.exec(this, {
|
||||
project: Fixtures.projectPath('config-with-invalid-browser'),
|
||||
project: 'config-with-invalid-browser',
|
||||
expectedExitCode: 1,
|
||||
snapshot: true,
|
||||
})
|
||||
@@ -46,37 +46,38 @@ describe('e2e config', () => {
|
||||
|
||||
it('supports global shadow dom inclusion', function () {
|
||||
return systemTests.exec(this, {
|
||||
project: Fixtures.projectPath('shadow-dom-global-inclusion'),
|
||||
project: 'shadow-dom-global-inclusion',
|
||||
})
|
||||
})
|
||||
|
||||
it('supports custom configFile in JavaScript', function () {
|
||||
return systemTests.exec(this, {
|
||||
project: Fixtures.projectPath('config-with-custom-file-js'),
|
||||
project: 'config-with-custom-file-js',
|
||||
configFile: 'cypress.config.custom.js',
|
||||
})
|
||||
})
|
||||
|
||||
it('supports custom configFile in TypeScript', function () {
|
||||
return systemTests.exec(this, {
|
||||
project: Fixtures.projectPath('config-with-custom-file-ts'),
|
||||
project: 'config-with-custom-file-ts',
|
||||
configFile: 'cypress.config.custom.ts',
|
||||
})
|
||||
})
|
||||
|
||||
it('supports custom configFile in a default JavaScript file', function () {
|
||||
return systemTests.exec(this, {
|
||||
project: Fixtures.projectPath('config-with-js'),
|
||||
project: 'config-with-js',
|
||||
})
|
||||
})
|
||||
|
||||
it('supports custom configFile in a default TypeScript file', function () {
|
||||
return systemTests.exec(this, {
|
||||
project: Fixtures.projectPath('config-with-ts'),
|
||||
project: 'config-with-ts',
|
||||
})
|
||||
})
|
||||
|
||||
it('throws error when multiple default config file are found in project', function () {
|
||||
Fixtures.scaffoldProject('pristine')
|
||||
const projectRoot = Fixtures.projectPath('pristine')
|
||||
|
||||
return Promise.all([
|
||||
@@ -84,7 +85,7 @@ describe('e2e config', () => {
|
||||
fs.writeFile(path.join(projectRoot, 'cypress.config.ts'), 'export default {}'),
|
||||
]).then(() => {
|
||||
return systemTests.exec(this, {
|
||||
project: projectRoot,
|
||||
project: 'pristine',
|
||||
expectedExitCode: 1,
|
||||
snapshot: true,
|
||||
})
|
||||
|
||||
@@ -4,16 +4,13 @@ const path = require('path')
|
||||
const systemTests = require('../lib/system-tests').default
|
||||
const Fixtures = require('../lib/fixtures')
|
||||
|
||||
const nonExistentSpec = Fixtures.projectPath('non-existent-spec')
|
||||
const e2eProject = Fixtures.projectPath('e2e')
|
||||
|
||||
describe('e2e plugins', () => {
|
||||
systemTests.setup()
|
||||
|
||||
it('fails when spec does not exist', function () {
|
||||
return systemTests.exec(this, {
|
||||
spec: 'spec.js',
|
||||
project: nonExistentSpec,
|
||||
project: 'non-existent-spec',
|
||||
sanitizeScreenshotDimensions: true,
|
||||
snapshot: true,
|
||||
expectedExitCode: 1,
|
||||
@@ -22,6 +19,7 @@ describe('e2e plugins', () => {
|
||||
|
||||
it('handles specs with $, &, and + in file name', function () {
|
||||
const relativeSpecPath = path.join('dir&1%', '%dir2&', 's%p+ec&.js')
|
||||
const e2eProject = Fixtures.projectPath('e2e')
|
||||
const specPath = path.join(e2eProject, 'cypress', 'integration', relativeSpecPath)
|
||||
|
||||
return fs.outputFile(specPath, 'it(\'passes\', () => {})')
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import systemTests from '../lib/system-tests'
|
||||
import Fixtures from '../lib/fixtures'
|
||||
|
||||
const beforeBrowserLaunchProject = Fixtures.projectPath('plugin-before-browser-launch-deprecation')
|
||||
const beforeBrowserLaunchProject = 'plugin-before-browser-launch-deprecation'
|
||||
|
||||
describe('deprecated before:browser:launch args', () => {
|
||||
systemTests.setup()
|
||||
|
||||
@@ -10,7 +10,7 @@ describe('e2e downloads', () => {
|
||||
systemTests.setup()
|
||||
|
||||
systemTests.it('handles various file downloads', {
|
||||
project: downloadsProject,
|
||||
project: 'downloads',
|
||||
spec: 'downloads_spec.ts',
|
||||
config: {
|
||||
video: false,
|
||||
@@ -18,11 +18,11 @@ describe('e2e downloads', () => {
|
||||
})
|
||||
|
||||
const fileExists = (fileName) => {
|
||||
return fs.pathExists(path.join(Fixtures.projectPath('downloads'), 'cypress', 'dls', fileName))
|
||||
return fs.pathExists(path.join(downloadsProject, 'cypress', 'dls', fileName))
|
||||
}
|
||||
|
||||
systemTests.it('allows changing the downloads folder', {
|
||||
project: Fixtures.projectPath('downloads'),
|
||||
project: 'downloads',
|
||||
spec: '*',
|
||||
config: {
|
||||
downloadsFolder: 'cypress/dls',
|
||||
@@ -39,13 +39,13 @@ describe('e2e downloads', () => {
|
||||
|
||||
it('trashes downloads between runs', async function () {
|
||||
await systemTests.exec(this, {
|
||||
project: downloadsProject,
|
||||
project: 'downloads',
|
||||
spec: 'download_csv_spec.ts',
|
||||
})
|
||||
|
||||
// this run should trash the downloads from the above run
|
||||
await systemTests.exec(this, {
|
||||
project: downloadsProject,
|
||||
project: 'downloads',
|
||||
spec: 'simple_passing_spec.ts',
|
||||
})
|
||||
|
||||
@@ -57,13 +57,13 @@ describe('e2e downloads', () => {
|
||||
|
||||
it('does not trash downloads between runs if trashAssetsBeforeRuns: false', async function () {
|
||||
await systemTests.exec(this, {
|
||||
project: downloadsProject,
|
||||
project: 'downloads',
|
||||
spec: 'download_csv_spec.ts',
|
||||
})
|
||||
|
||||
// this run should _not_ trash the downloads from the above run
|
||||
await systemTests.exec(this, {
|
||||
project: downloadsProject,
|
||||
project: 'downloads',
|
||||
spec: 'simple_passing_spec.ts',
|
||||
config: {
|
||||
trashAssetsBeforeRuns: false,
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import systemTests, { expect } from '../lib/system-tests'
|
||||
import Fixtures from '../lib/fixtures'
|
||||
import path from 'path'
|
||||
|
||||
const verifyPassedAndFailedAreSame = (expectedFailures) => {
|
||||
return ({ stdout }) => {
|
||||
@@ -13,6 +12,10 @@ const verifyPassedAndFailedAreSame = (expectedFailures) => {
|
||||
describe('e2e error ui', function () {
|
||||
systemTests.setup()
|
||||
|
||||
beforeEach(() => {
|
||||
Fixtures.scaffoldProject('e2e')
|
||||
})
|
||||
|
||||
;[
|
||||
'webpack-preprocessor',
|
||||
'webpack-preprocessor-ts-loader',
|
||||
@@ -23,7 +26,7 @@ describe('e2e error ui', function () {
|
||||
]
|
||||
.forEach((project) => {
|
||||
systemTests.it(`handles sourcemaps in webpack for project: ${project}`, {
|
||||
project: Fixtures.projectPath(project),
|
||||
project,
|
||||
spec: 'failing_spec.*',
|
||||
expectedExitCode: 1,
|
||||
onRun (exec) {
|
||||
@@ -34,10 +37,12 @@ describe('e2e error ui', function () {
|
||||
|
||||
// https://github.com/cypress-io/cypress/issues/16255
|
||||
systemTests.it('handles errors when integration folder is outside of project root', {
|
||||
project: path.join(Fixtures.projectPath('integration-outside-project-root'), 'project-root'),
|
||||
project: 'integration-outside-project-root/project-root',
|
||||
spec: '../../../integration/failing_spec.js',
|
||||
expectedExitCode: 1,
|
||||
onRun (exec) {
|
||||
Fixtures.scaffoldProject('integration-outside-project-root')
|
||||
|
||||
return exec().then(verifyPassedAndFailedAreSame(1))
|
||||
},
|
||||
})
|
||||
|
||||
@@ -17,7 +17,7 @@ describe('e2e firefox', function () {
|
||||
// @see https://github.com/cypress-io/cypress/issues/6187
|
||||
systemTests.it.skip('can run a lot of tests', {
|
||||
outputPath,
|
||||
project: Fixtures.projectPath('firefox-memory'),
|
||||
project: 'firefox-memory',
|
||||
spec: 'spec.js',
|
||||
browser: 'firefox',
|
||||
expectedExitCode: 0,
|
||||
@@ -54,7 +54,7 @@ describe('e2e firefox', function () {
|
||||
|
||||
systemTests.it('launches maximized by default', {
|
||||
browser: 'firefox',
|
||||
project: Fixtures.projectPath('screen-size'),
|
||||
project: 'screen-size',
|
||||
spec: 'maximized.spec.js',
|
||||
onRun: async (exec) => {
|
||||
const { stderr } = await exec({
|
||||
@@ -73,7 +73,7 @@ describe('e2e firefox', function () {
|
||||
// https://github.com/cypress-io/cypress/issues/6392
|
||||
systemTests.it.skip('can run multiple specs', {
|
||||
browser: 'firefox',
|
||||
project: Fixtures.projectPath('e2e'),
|
||||
project: 'e2e',
|
||||
spec: 'simple_spec.js,simple_passing_spec.js',
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import systemTests from '../lib/system-tests'
|
||||
import Fixtures from '../lib/fixtures'
|
||||
|
||||
describe('e2e headless', function () {
|
||||
systemTests.setup()
|
||||
@@ -81,13 +80,13 @@ describe('e2e headless', function () {
|
||||
|
||||
systemTests.it('launches maximized by default in headless mode (1920x1080)', {
|
||||
headed: false,
|
||||
project: Fixtures.projectPath('screen-size'),
|
||||
project: 'screen-size',
|
||||
spec: 'default_size.spec.js',
|
||||
})
|
||||
|
||||
systemTests.it('launches at DPR 1x', {
|
||||
headed: false,
|
||||
project: Fixtures.projectPath('screen-size'),
|
||||
project: 'screen-size',
|
||||
spec: 'device_pixel_ratio.spec.js',
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
const systemTests = require('../lib/system-tests').default
|
||||
const Fixtures = require('../lib/fixtures')
|
||||
|
||||
describe('e2e issue 2891', () => {
|
||||
systemTests.setup()
|
||||
@@ -7,7 +6,7 @@ describe('e2e issue 2891', () => {
|
||||
// https://github.com/cypress-io/cypress/issues/2891
|
||||
it('passes', function () {
|
||||
return systemTests.exec(this, {
|
||||
project: Fixtures.projectPath('default-layout'),
|
||||
project: 'default-layout',
|
||||
spec: 'default_layout_spec.js',
|
||||
sanitizeScreenshotDimensions: true,
|
||||
snapshot: true,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
const systemTests = require('../lib/system-tests').default
|
||||
const Fixtures = require('../lib/fixtures')
|
||||
|
||||
describe('e2e issue 8111 iframe input focus', function () {
|
||||
systemTests.setup()
|
||||
@@ -8,7 +7,7 @@ describe('e2e issue 8111 iframe input focus', function () {
|
||||
// this test is dependent on the browser being Chrome headed
|
||||
// and also having --auto-open-devtools-for-tabs plugins option
|
||||
// (which pulls focus from main browser window)
|
||||
project: Fixtures.projectPath('issue-8111-iframe-input'),
|
||||
project: 'issue-8111-iframe-input',
|
||||
spec: 'iframe_input_spec.js',
|
||||
browser: 'chrome',
|
||||
headed: true,
|
||||
|
||||
@@ -13,7 +13,7 @@ describe('max listeners warning spec', () => {
|
||||
// @see https://github.com/cypress-io/cypress/issues/1305
|
||||
systemTests.it('does not log MaxEventListeners error', {
|
||||
browser: 'electron',
|
||||
project: projectPath,
|
||||
project: 'max-listeners',
|
||||
spec: '*',
|
||||
processEnv: {
|
||||
CYPRESS_INTERNAL_ENV: 'production',
|
||||
|
||||
@@ -16,7 +16,7 @@ describe('e2e new project', () => {
|
||||
throw new Error('support folder should not exist')
|
||||
}).catch(() => {
|
||||
return systemTests.exec(this, {
|
||||
project: noScaffoldingPath,
|
||||
project: 'no-scaffolding',
|
||||
sanitizeScreenshotDimensions: true,
|
||||
snapshot: true,
|
||||
})
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import systemTests from '../lib/system-tests'
|
||||
import Fixtures from '../lib/fixtures'
|
||||
|
||||
describe('e2e non-proxied spec', () => {
|
||||
systemTests.setup()
|
||||
@@ -10,7 +9,7 @@ describe('e2e non-proxied spec', () => {
|
||||
video: false,
|
||||
},
|
||||
browser: 'chrome',
|
||||
project: Fixtures.projectPath('non-proxied'),
|
||||
project: 'non-proxied',
|
||||
snapshot: true,
|
||||
})
|
||||
})
|
||||
|
||||
@@ -22,22 +22,25 @@ describe('e2e readonly fs', function () {
|
||||
}
|
||||
}
|
||||
|
||||
const onRun = (exec) => {
|
||||
const onRun = async (exec) => {
|
||||
Fixtures.scaffoldProject('read-only-project-root')
|
||||
await Fixtures.scaffoldCommonNodeModules()
|
||||
chmodr(projectPath, 0o500)
|
||||
|
||||
return exec().finally(() => {
|
||||
chmodr(projectPath, 0o777)
|
||||
})
|
||||
await exec()
|
||||
|
||||
chmodr(projectPath, 0o777)
|
||||
}
|
||||
|
||||
systemTests.it('warns when unable to write to disk', {
|
||||
project: projectPath,
|
||||
project: 'read-only-project-root',
|
||||
expectedExitCode: 1,
|
||||
spec: 'spec.js',
|
||||
snapshot: true,
|
||||
config: {
|
||||
video: false,
|
||||
},
|
||||
skipScaffold: true,
|
||||
onRun,
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import systemTests from '../lib/system-tests'
|
||||
import Fixtures from '../lib/fixtures'
|
||||
|
||||
describe('e2e plugin run events', () => {
|
||||
systemTests.setup()
|
||||
|
||||
systemTests.it('sends events', {
|
||||
browser: 'electron',
|
||||
project: Fixtures.projectPath('plugin-run-events'),
|
||||
project: 'plugin-run-events',
|
||||
spec: '*',
|
||||
snapshot: true,
|
||||
config: {
|
||||
@@ -16,14 +15,14 @@ describe('e2e plugin run events', () => {
|
||||
|
||||
systemTests.it('handles video being deleted in after:spec', {
|
||||
browser: 'electron',
|
||||
project: Fixtures.projectPath('plugin-after-spec-deletes-video'),
|
||||
project: 'plugin-after-spec-deletes-video',
|
||||
spec: '*',
|
||||
snapshot: true,
|
||||
})
|
||||
|
||||
systemTests.it('fails run if event handler throws', {
|
||||
browser: 'electron',
|
||||
project: Fixtures.projectPath('plugin-run-event-throws'),
|
||||
project: 'plugin-run-event-throws',
|
||||
spec: '*',
|
||||
snapshot: true,
|
||||
expectedExitCode: 1,
|
||||
|
||||
@@ -15,7 +15,7 @@ describe('e2e plugins', function () {
|
||||
systemTests.it('fails when there is an async error at the root', {
|
||||
browser: 'chrome',
|
||||
spec: 'app_spec.js',
|
||||
project: Fixtures.projectPath('plugins-root-async-error'),
|
||||
project: 'plugins-root-async-error',
|
||||
expectedExitCode: 1,
|
||||
onRun (exec) {
|
||||
return exec().then(({ stdout }) => {
|
||||
@@ -28,7 +28,7 @@ describe('e2e plugins', function () {
|
||||
it('fails when there is an async error inside an event handler', function () {
|
||||
return systemTests.exec(this, {
|
||||
spec: 'app_spec.js',
|
||||
project: Fixtures.projectPath('plugins-async-error'),
|
||||
project: 'plugins-async-error',
|
||||
sanitizeScreenshotDimensions: true,
|
||||
snapshot: true,
|
||||
expectedExitCode: 1,
|
||||
@@ -43,7 +43,7 @@ describe('e2e plugins', function () {
|
||||
spec: 'app_spec.js',
|
||||
env: 'foo=foo,bar=bar',
|
||||
config: { pageLoadTimeout: 10000 },
|
||||
project: Fixtures.projectPath('plugin-config'),
|
||||
project: 'plugin-config',
|
||||
sanitizeScreenshotDimensions: true,
|
||||
snapshot: true,
|
||||
})
|
||||
@@ -51,14 +51,14 @@ describe('e2e plugins', function () {
|
||||
|
||||
it('passes version correctly', function () {
|
||||
return systemTests.exec(this, {
|
||||
project: Fixtures.projectPath('plugin-config-version'),
|
||||
project: 'plugin-config-version',
|
||||
})
|
||||
})
|
||||
|
||||
it('catches invalid viewportWidth returned from plugins', function () {
|
||||
// the test project returns config object with a bad value
|
||||
return systemTests.exec(this, {
|
||||
project: Fixtures.projectPath('plugin-returns-bad-config'),
|
||||
project: 'plugin-returns-bad-config',
|
||||
expectedExitCode: 1,
|
||||
snapshot: true,
|
||||
})
|
||||
@@ -66,7 +66,7 @@ describe('e2e plugins', function () {
|
||||
|
||||
it('catches invalid browsers list returned from plugins', function () {
|
||||
return systemTests.exec(this, {
|
||||
project: Fixtures.projectPath('plugin-returns-empty-browsers-list'),
|
||||
project: 'plugin-returns-empty-browsers-list',
|
||||
expectedExitCode: 1,
|
||||
snapshot: true,
|
||||
})
|
||||
@@ -74,7 +74,7 @@ describe('e2e plugins', function () {
|
||||
|
||||
it('catches invalid browser returned from plugins', function () {
|
||||
return systemTests.exec(this, {
|
||||
project: Fixtures.projectPath('plugin-returns-invalid-browser'),
|
||||
project: 'plugin-returns-invalid-browser',
|
||||
expectedExitCode: 1,
|
||||
snapshot: true,
|
||||
})
|
||||
@@ -82,7 +82,7 @@ describe('e2e plugins', function () {
|
||||
|
||||
it('can filter browsers from config', function () {
|
||||
return systemTests.exec(this, {
|
||||
project: Fixtures.projectPath('plugin-filter-browsers'),
|
||||
project: 'plugin-filter-browsers',
|
||||
// the test project filters available browsers
|
||||
// and returns a list with JUST Electron browser
|
||||
// and we ask to run in Chrome
|
||||
@@ -100,7 +100,7 @@ describe('e2e plugins', function () {
|
||||
browser: 'chrome',
|
||||
spec: 'app_spec.js',
|
||||
headed: true,
|
||||
project: Fixtures.projectPath('plugin-extension'),
|
||||
project: 'plugin-extension',
|
||||
sanitizeScreenshotDimensions: true,
|
||||
snapshot: true,
|
||||
})
|
||||
@@ -116,13 +116,13 @@ describe('e2e plugins', function () {
|
||||
'cypress/plugins/index.js',
|
||||
),
|
||||
},
|
||||
project: pluginsAbsolutePath,
|
||||
project: 'plugins-absolute-path',
|
||||
sanitizeScreenshotDimensions: true,
|
||||
snapshot: true,
|
||||
})
|
||||
})
|
||||
|
||||
const pluginAfterScreenshot = Fixtures.projectPath('plugin-after-screenshot')
|
||||
const pluginAfterScreenshot = 'plugin-after-screenshot'
|
||||
|
||||
it('calls after:screenshot for cy.screenshot() and failure screenshots', function () {
|
||||
return systemTests.exec(this, {
|
||||
@@ -146,7 +146,7 @@ describe('e2e plugins', function () {
|
||||
it('fails when invalid event is registered', function () {
|
||||
return systemTests.exec(this, {
|
||||
spec: 'app_spec.js',
|
||||
project: Fixtures.projectPath('plugin-validation-error'),
|
||||
project: 'plugin-validation-error',
|
||||
sanitizeScreenshotDimensions: true,
|
||||
snapshot: true,
|
||||
expectedExitCode: 1,
|
||||
@@ -156,7 +156,7 @@ describe('e2e plugins', function () {
|
||||
it('fails when there is no function exported', function () {
|
||||
return systemTests.exec(this, {
|
||||
spec: 'app_spec.js',
|
||||
project: Fixtures.projectPath('plugin-empty'),
|
||||
project: 'plugin-empty',
|
||||
sanitizeScreenshotDimensions: true,
|
||||
snapshot: true,
|
||||
expectedExitCode: 1,
|
||||
@@ -167,7 +167,7 @@ describe('e2e plugins', function () {
|
||||
it('passes with working preprocessor', function () {
|
||||
return systemTests.exec(this, {
|
||||
spec: 'app_spec.js',
|
||||
project: Fixtures.projectPath('working-preprocessor'),
|
||||
project: 'working-preprocessor',
|
||||
sanitizeScreenshotDimensions: true,
|
||||
snapshot: true,
|
||||
})
|
||||
|
||||
@@ -360,7 +360,7 @@ describe('e2e record', () => {
|
||||
trashAssetsBeforeRuns: false,
|
||||
},
|
||||
})
|
||||
.get('stdout'),
|
||||
.then(({ stdout }) => stdout),
|
||||
|
||||
// stagger the 2nd run
|
||||
// starting up a bit
|
||||
@@ -380,7 +380,7 @@ describe('e2e record', () => {
|
||||
trashAssetsBeforeRuns: false,
|
||||
},
|
||||
})
|
||||
.get('stdout')
|
||||
.then(({ stdout }) => stdout)
|
||||
}),
|
||||
])
|
||||
})
|
||||
|
||||
@@ -70,8 +70,7 @@ describe('e2e reporters', () => {
|
||||
spec: 'simple_passing_spec.js',
|
||||
reporter: 'reporters/uses-file.js',
|
||||
})
|
||||
.get('stdout')
|
||||
.then((stdout) => {
|
||||
.then(({ stdout }) => {
|
||||
expect(stdout).to.include('suite.file: cypress/integration/simple_passing_spec.js')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import systemTests from '../lib/system-tests'
|
||||
import Fixtures from '../lib/fixtures'
|
||||
|
||||
const it = systemTests.it
|
||||
|
||||
@@ -7,7 +6,7 @@ describe('retries', () => {
|
||||
systemTests.setup()
|
||||
|
||||
it('supports retries', {
|
||||
project: Fixtures.projectPath('retries-2'),
|
||||
project: 'retries-2',
|
||||
spec: 'fail-twice.js',
|
||||
snapshot: true,
|
||||
})
|
||||
@@ -18,9 +17,8 @@ describe('retries', () => {
|
||||
})
|
||||
|
||||
it('warns about retries plugin', {
|
||||
project: Fixtures.projectPath('plugin-retries'),
|
||||
project: 'plugin-retries',
|
||||
spec: 'main.spec.js',
|
||||
stubPackage: 'cypress-plugin-retries',
|
||||
snapshot: true,
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import systemTests from '../lib/system-tests'
|
||||
import Fixtures from '../lib/fixtures'
|
||||
|
||||
describe('e2e runnable execution', () => {
|
||||
systemTests.setup({
|
||||
@@ -21,14 +20,14 @@ describe('e2e runnable execution', () => {
|
||||
// but throws correct error
|
||||
// https://github.com/cypress-io/cypress/issues/1987
|
||||
systemTests.it('cannot navigate in before hook and test', {
|
||||
project: Fixtures.projectPath('hooks-after-rerun'),
|
||||
project: 'hooks-after-rerun',
|
||||
spec: 'beforehook-and-test-navigation.js',
|
||||
snapshot: true,
|
||||
expectedExitCode: 2,
|
||||
})
|
||||
|
||||
systemTests.it('runnables run correct number of times with navigation', {
|
||||
project: Fixtures.projectPath('hooks-after-rerun'),
|
||||
project: 'hooks-after-rerun',
|
||||
spec: 'runnable-run-count.spec.js',
|
||||
snapshot: true,
|
||||
})
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
const systemTests = require('../lib/system-tests').default
|
||||
const Fixtures = require('../lib/fixtures')
|
||||
|
||||
describe('e2e specs', () => {
|
||||
systemTests.setup()
|
||||
@@ -22,30 +21,24 @@ describe('e2e specs', () => {
|
||||
|
||||
// @see https://github.com/cypress-io/cypress/issues/14226
|
||||
it('handles the same integration and fixtures folders', function () {
|
||||
const project = Fixtures.projectPath('same-fixtures-integration-folders')
|
||||
|
||||
return systemTests.exec(this, {
|
||||
project,
|
||||
project: 'same-fixtures-integration-folders',
|
||||
snapshot: false,
|
||||
expectedExitCode: 0,
|
||||
})
|
||||
})
|
||||
|
||||
it('handles the fixtures folder being the subfolder of integration', function () {
|
||||
const project = Fixtures.projectPath('fixture-subfolder-of-integration')
|
||||
|
||||
return systemTests.exec(this, {
|
||||
project,
|
||||
project: 'fixture-subfolder-of-integration',
|
||||
snapshot: false,
|
||||
expectedExitCode: 0,
|
||||
})
|
||||
})
|
||||
|
||||
it('handles specs with special characters in the file name', function () {
|
||||
const project = Fixtures.projectPath('spec-name-special-characters')
|
||||
|
||||
return systemTests.exec(this, {
|
||||
project,
|
||||
project: 'spec-name-special-characters',
|
||||
snapshot: false,
|
||||
expectedExitCode: 0,
|
||||
})
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import path from 'path'
|
||||
import systemTests from '../lib/system-tests'
|
||||
import { projectPath } from '../lib/fixtures'
|
||||
import Fixtures, { projectPath } from '../lib/fixtures'
|
||||
import { promises as fs } from 'fs'
|
||||
|
||||
const snapshotFile = (project, file, folder = 'integration') => {
|
||||
@@ -20,7 +20,7 @@ describe.skip('e2e studio', function () {
|
||||
systemTests.setup()
|
||||
|
||||
systemTests.it('extends test', {
|
||||
project: projectPath('studio'),
|
||||
project: 'studio',
|
||||
spec: 'extend.spec.js',
|
||||
snapshot: true,
|
||||
browser: 'electron',
|
||||
@@ -32,7 +32,7 @@ describe.skip('e2e studio', function () {
|
||||
// includes "New Test" in snapshot
|
||||
// this is the blank new test that's being created
|
||||
systemTests.it('creates new test', {
|
||||
project: projectPath('studio'),
|
||||
project: 'studio',
|
||||
spec: 'new.spec.js',
|
||||
browser: 'electron',
|
||||
snapshot: true,
|
||||
@@ -42,7 +42,7 @@ describe.skip('e2e studio', function () {
|
||||
})
|
||||
|
||||
systemTests.it('can write to imported files', {
|
||||
project: projectPath('studio'),
|
||||
project: 'studio',
|
||||
spec: 'external.spec.js',
|
||||
snapshot: true,
|
||||
browser: 'electron',
|
||||
@@ -55,21 +55,25 @@ describe.skip('e2e studio', function () {
|
||||
})
|
||||
|
||||
systemTests.it('extends test without source maps', {
|
||||
project: projectPath('studio-no-source-maps'),
|
||||
project: 'studio-no-source-maps',
|
||||
spec: 'extend.spec.js',
|
||||
snapshot: true,
|
||||
browser: 'electron',
|
||||
onRun (exec) {
|
||||
Fixtures.scaffoldProject('studio')
|
||||
|
||||
return exec().then(() => snapshotFile('studio-no-source-maps', 'extend.spec.js'))
|
||||
},
|
||||
})
|
||||
|
||||
systemTests.it('creates new test without source maps', {
|
||||
project: projectPath('studio-no-source-maps'),
|
||||
project: 'studio-no-source-maps',
|
||||
spec: 'new.spec.js',
|
||||
browser: 'electron',
|
||||
snapshot: true,
|
||||
onRun (exec) {
|
||||
Fixtures.scaffoldProject('studio')
|
||||
|
||||
return exec().then(() => snapshotFile('studio-no-source-maps', 'new.spec.js'))
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
const systemTests = require('../lib/system-tests').default
|
||||
const execa = require('execa')
|
||||
const Fixtures = require('../lib/fixtures')
|
||||
|
||||
const systemNode = Fixtures.projectPath('system-node')
|
||||
|
||||
let expectedNodeVersion
|
||||
let expectedNodePath
|
||||
@@ -18,7 +15,7 @@ describe('e2e system node', () => {
|
||||
|
||||
it('uses system node when launching plugins file', async function () {
|
||||
const { stderr } = await systemTests.exec(this, {
|
||||
project: systemNode,
|
||||
project: 'system-node',
|
||||
userNodePath: expectedNodePath,
|
||||
userNodeVersion: expectedNodeVersion,
|
||||
config: {
|
||||
@@ -40,7 +37,7 @@ describe('e2e system node', () => {
|
||||
|
||||
it('uses bundled node when launching plugins file', async function () {
|
||||
const { stderr } = await systemTests.exec(this, {
|
||||
project: systemNode,
|
||||
project: 'system-node',
|
||||
config: {
|
||||
nodeVersion: 'bundled',
|
||||
env: {
|
||||
@@ -59,7 +56,7 @@ describe('e2e system node', () => {
|
||||
|
||||
it('uses default node when launching plugins file', async function () {
|
||||
const { stderr } = await systemTests.exec(this, {
|
||||
project: systemNode,
|
||||
project: 'system-node',
|
||||
userNodePath: expectedNodePath,
|
||||
userNodeVersion: expectedNodeVersion,
|
||||
config: {
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
const systemTests = require('../lib/system-tests').default
|
||||
const Fixtures = require('../lib/fixtures')
|
||||
|
||||
describe('e2e task', () => {
|
||||
systemTests.setup()
|
||||
|
||||
it('fails', function () {
|
||||
return systemTests.exec(this, {
|
||||
project: Fixtures.projectPath('task-not-registered'),
|
||||
project: 'task-not-registered',
|
||||
spec: 'task_not_registered_spec.js',
|
||||
sanitizeScreenshotDimensions: true,
|
||||
snapshot: true,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
const systemTests = require('../lib/system-tests').default
|
||||
const Fixtures = require('../lib/fixtures')
|
||||
|
||||
describe('e2e task', () => {
|
||||
systemTests.setup()
|
||||
@@ -22,7 +21,7 @@ describe('e2e task', () => {
|
||||
|
||||
it('merges task events on subsequent registrations and logs warning for conflicts', function () {
|
||||
return systemTests.exec(this, {
|
||||
project: Fixtures.projectPath('multiple-task-registrations'),
|
||||
project: 'multiple-task-registrations',
|
||||
spec: 'multiple_task_registrations_spec.js',
|
||||
sanitizeScreenshotDimensions: true,
|
||||
snapshot: true,
|
||||
|
||||
@@ -1,33 +1,32 @@
|
||||
import systemTests from '../lib/system-tests'
|
||||
import Fixtures from '../lib/fixtures'
|
||||
|
||||
describe('e2e typescript in plugins file', function () {
|
||||
systemTests.setup()
|
||||
|
||||
it('handles tsconfig with module other than commonjs', function () {
|
||||
return systemTests.exec(this, {
|
||||
project: Fixtures.projectPath('ts-proj-with-module-esnext'),
|
||||
project: 'ts-proj-with-module-esnext',
|
||||
})
|
||||
})
|
||||
|
||||
// https://github.com/cypress-io/cypress/issues/7575
|
||||
it('defaults to esModuleInterop: false', function () {
|
||||
return systemTests.exec(this, {
|
||||
project: Fixtures.projectPath('ts-proj'),
|
||||
project: 'ts-proj',
|
||||
})
|
||||
})
|
||||
|
||||
// https://github.com/cypress-io/cypress/issues/7575
|
||||
it('allows esModuleInterop to be overridden with true via tsconfig.json', function () {
|
||||
return systemTests.exec(this, {
|
||||
project: Fixtures.projectPath('ts-proj-esmoduleinterop-true'),
|
||||
project: 'ts-proj-esmoduleinterop-true',
|
||||
})
|
||||
})
|
||||
|
||||
// https://github.com/cypress-io/cypress/issues/8359
|
||||
it('loads tsconfig.json from plugins directory', function () {
|
||||
return systemTests.exec(this, {
|
||||
project: Fixtures.projectPath('ts-proj-tsconfig-in-plugins'),
|
||||
project: 'ts-proj-tsconfig-in-plugins',
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import systemTests from '../lib/system-tests'
|
||||
import Fixtures from '../lib/fixtures'
|
||||
|
||||
describe('e2e typescript in spec and support file', function () {
|
||||
systemTests.setup()
|
||||
@@ -16,15 +15,17 @@ describe('e2e typescript in spec and support file', function () {
|
||||
spec: 'typescript_syntax_error_spec.ts',
|
||||
snapshot: true,
|
||||
expectedExitCode: 1,
|
||||
onStdout: systemTests.normalizeWebpackErrors,
|
||||
onStdout: (stdout) => {
|
||||
stdout = stdout.replace(new RegExp('^(.*)npm/(webpack-batteries-included-preprocessor/node_modules/ts-loader/index.js)$', 'm'), ' * relative/path/to/$2')
|
||||
|
||||
return systemTests.normalizeWebpackErrors(stdout)
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
it('project passes', function () {
|
||||
const projPath = Fixtures.projectPath('ts-proj')
|
||||
|
||||
return systemTests.exec(this, {
|
||||
project: projPath,
|
||||
project: 'ts-proj',
|
||||
snapshot: true,
|
||||
})
|
||||
})
|
||||
@@ -34,7 +35,7 @@ describe('e2e typescript in spec and support file', function () {
|
||||
// @see https://github.com/cypress-io/cypress/issues/8555
|
||||
it('respects tsconfig paths', function () {
|
||||
return systemTests.exec(this, {
|
||||
project: Fixtures.projectPath('ts-proj-with-paths'),
|
||||
project: 'ts-proj-with-paths',
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
const systemTests = require('../lib/system-tests').default
|
||||
const Fixtures = require('../lib/fixtures')
|
||||
|
||||
const uncaughtSupportFile = Fixtures.projectPath('uncaught-support-file')
|
||||
|
||||
describe('e2e uncaught support file errors', () => {
|
||||
systemTests.setup()
|
||||
|
||||
it('failing', function () {
|
||||
return systemTests.exec(this, {
|
||||
project: uncaughtSupportFile,
|
||||
project: 'uncaught-support-file',
|
||||
sanitizeScreenshotDimensions: true,
|
||||
snapshot: true,
|
||||
expectedExitCode: 1,
|
||||
|
||||
@@ -49,58 +49,48 @@ describe('e2e video compression', () => {
|
||||
MS_PER_TEST,
|
||||
},
|
||||
},
|
||||
onRun (exec) {
|
||||
async onRun (exec) {
|
||||
process.env.VIDEO_COMPRESSION_THROTTLE = 10
|
||||
|
||||
return exec()
|
||||
.tap(() => {
|
||||
const videosPath = Fixtures.projectPath('e2e/cypress/videos/*')
|
||||
const { stdout } = await exec()
|
||||
const videosPath = Fixtures.projectPath('e2e/cypress/videos/*')
|
||||
const files = await glob(videosPath)
|
||||
|
||||
return glob(videosPath)
|
||||
.tap(async (files) => {
|
||||
expect(files).to.have.length(1, `globbed for videos and found: ${files.length}. Expected to find 1 video. Search in videosPath: ${videosPath}.`)
|
||||
expect(files).to.have.length(1, `globbed for videos and found: ${files.length}. Expected to find 1 video. Search in videosPath: ${videosPath}.`)
|
||||
|
||||
const lastFrameFile = path.join(path.dirname(files[0]), 'lastFrame.jpg')
|
||||
const lastFrameFile = path.join(path.dirname(files[0]), 'lastFrame.jpg')
|
||||
|
||||
await outputFinalFrameAsJpg(files[0], lastFrameFile)
|
||||
// https://github.com/cypress-io/cypress/issues/9265
|
||||
// if video is seekable and not just one frozen frame, this file should exist
|
||||
await fs.stat(lastFrameFile).catch((err) => {
|
||||
throw new Error(`Expected video to have seekable ending frame, but it did not. The video may be corrupted.`)
|
||||
})
|
||||
|
||||
return videoCapture.getCodecData(files[0])
|
||||
.then(({ duration }) => {
|
||||
const durationMs = videoCapture.getMsFromDuration(duration)
|
||||
|
||||
expect(durationMs).to.be.ok
|
||||
|
||||
expect(durationMs).to.be.closeTo(EXPECTED_DURATION_MS, humanInterval('15 seconds'))
|
||||
})
|
||||
})
|
||||
.then((files) => {
|
||||
return videoCapture.getChapters(files[0])
|
||||
.then(({ chapters }) => {
|
||||
// There are 40 chapters but we test only the first one
|
||||
// because what we want to check is if chapters are added properly.
|
||||
// In a chapter object, there are properties like 'end' and 'end_time'.
|
||||
// We don't check them here because they return the test time in milliseconds.
|
||||
// They cannot be guessed correctly and they can cause flakiness.
|
||||
expect(chapters[0].id).to.eq(0)
|
||||
expect(chapters[0].start).to.eq(0)
|
||||
expect(chapters[0].start_time).to.eq(0)
|
||||
expect(chapters[0]['TAG:title']).to.eq('num: 1 makes some long tests')
|
||||
expect(chapters[0].time_base).to.eq('1/1000')
|
||||
expect(chapters[0].end).to.be.a('number')
|
||||
expect(Number.isNaN(chapters[0].end)).to.be.false
|
||||
expect(chapters[0].end_time).to.be.a('number')
|
||||
expect(Number.isNaN(chapters[0].end_time)).to.be.false
|
||||
})
|
||||
})
|
||||
}).get('stdout')
|
||||
.then((stdout) => {
|
||||
expect(stdout).to.match(/Compression progress:\s+\d{1,3}%/)
|
||||
await outputFinalFrameAsJpg(files[0], lastFrameFile)
|
||||
// https://github.com/cypress-io/cypress/issues/9265
|
||||
// if video is seekable and not just one frozen frame, this file should exist
|
||||
await fs.stat(lastFrameFile).catch((err) => {
|
||||
throw new Error(`Expected video to have seekable ending frame, but it did not. The video may be corrupted.`)
|
||||
})
|
||||
|
||||
const { duration } = await videoCapture.getCodecData(files[0])
|
||||
const durationMs = videoCapture.getMsFromDuration(duration)
|
||||
|
||||
expect(durationMs).to.be.ok
|
||||
expect(durationMs).to.be.closeTo(EXPECTED_DURATION_MS, humanInterval('15 seconds'))
|
||||
|
||||
const { chapters } = await videoCapture.getChapters(files[0])
|
||||
|
||||
// There are 40 chapters but we test only the first one
|
||||
// because what we want to check is if chapters are added properly.
|
||||
// In a chapter object, there are properties like 'end' and 'end_time'.
|
||||
// We don't check them here because they return the test time in milliseconds.
|
||||
// They cannot be guessed correctly and they can cause flakiness.
|
||||
expect(chapters[0].id).to.eq(0)
|
||||
expect(chapters[0].start).to.eq(0)
|
||||
expect(chapters[0].start_time).to.eq(0)
|
||||
expect(chapters[0]['TAG:title']).to.eq('num: 1 makes some long tests')
|
||||
expect(chapters[0].time_base).to.eq('1/1000')
|
||||
expect(chapters[0].end).to.be.a('number')
|
||||
expect(Number.isNaN(chapters[0].end)).to.be.false
|
||||
expect(chapters[0].end_time).to.be.a('number')
|
||||
expect(Number.isNaN(chapters[0].end_time)).to.be.false
|
||||
|
||||
expect(stdout).to.match(/Compression progress:\s+\d{1,3}%/)
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,53 +1,16 @@
|
||||
import fs from 'fs-extra'
|
||||
import os from 'os'
|
||||
import path from 'path'
|
||||
import cp from 'child_process'
|
||||
import util from 'util'
|
||||
import systemTests from '../lib/system-tests'
|
||||
import Fixtures from '../lib/fixtures'
|
||||
|
||||
const exec = async (cmd, ...args) => {
|
||||
console.log(`Running "${cmd}"...`)
|
||||
const ret = await util.promisify(cp.exec)(cmd, ...args)
|
||||
.catch((err) => {
|
||||
console.error('Error:', err)
|
||||
|
||||
return err
|
||||
})
|
||||
|
||||
console.log('stdout:', ret.stdout)
|
||||
ret.stderr && console.log('stderr:', ret.stderr)
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
const fixtureDir = Fixtures.projectPath('yarn-v2-pnp')
|
||||
const cypressCli = path.join(__dirname, '../../cli/bin/cypress')
|
||||
const projectDir = Fixtures.projectPath('yarn-v2-pnp')
|
||||
|
||||
describe('e2e yarn v2', () => {
|
||||
let projectDir
|
||||
|
||||
beforeEach(async function () {
|
||||
Fixtures.scaffold()
|
||||
|
||||
this.timeout(240000)
|
||||
|
||||
// copy yarn-v2 to tmpdir so node_modules resolution won't fall back to project root
|
||||
projectDir = path.join(os.tmpdir(), `cy-yarn-v2-pnp-${Date.now()}`)
|
||||
console.log(`projectDir`, projectDir)
|
||||
|
||||
await fs.mkdir(projectDir)
|
||||
await fs.copy(fixtureDir, projectDir)
|
||||
|
||||
const projectExec = (cmd) => exec(cmd, { cwd: projectDir })
|
||||
|
||||
await projectExec('yarn')
|
||||
})
|
||||
|
||||
systemTests.it('can compile plugin and test specs', {
|
||||
snapshot: false,
|
||||
command: 'yarn',
|
||||
browser: 'electron',
|
||||
project: 'yarn-v2-pnp',
|
||||
onRun: async (run) => {
|
||||
await run({
|
||||
args: `node ${cypressCli} run --dev --project=./`.split(' '),
|
||||
|
||||
30
yarn.lock
30
yarn.lock
@@ -3469,7 +3469,7 @@
|
||||
|
||||
"@jest/types@^26.3.0", "@jest/types@^26.6.2":
|
||||
version "26.6.2"
|
||||
resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e"
|
||||
resolved "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e"
|
||||
integrity sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==
|
||||
dependencies:
|
||||
"@types/istanbul-lib-coverage" "^2.0.0"
|
||||
@@ -7687,7 +7687,7 @@
|
||||
|
||||
"@types/cheerio@*", "@types/cheerio@0.22.21":
|
||||
version "0.22.21"
|
||||
resolved "https://registry.yarnpkg.com/@types/cheerio/-/cheerio-0.22.21.tgz#5e37887de309ba11b2e19a6e14cad7874b31a8a3"
|
||||
resolved "https://registry.npmjs.org/@types/cheerio/-/cheerio-0.22.21.tgz#5e37887de309ba11b2e19a6e14cad7874b31a8a3"
|
||||
integrity sha512-aGI3DfswwqgKPiEOTaiHV2ZPC9KEhprpgEbJnv0fZl3SGX0cGgEva1126dGrMC6AJM6v/aihlUgJn9M5DbDZ/Q==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
@@ -7789,7 +7789,7 @@
|
||||
|
||||
"@types/enzyme@*", "@types/enzyme@3.10.5":
|
||||
version "3.10.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/enzyme/-/enzyme-3.10.5.tgz#fe7eeba3550369eed20e7fb565bfb74eec44f1f0"
|
||||
resolved "https://registry.npmjs.org/@types/enzyme/-/enzyme-3.10.5.tgz#fe7eeba3550369eed20e7fb565bfb74eec44f1f0"
|
||||
integrity sha512-R+phe509UuUYy9Tk0YlSbipRpfVtIzb/9BHn5pTEtjJTF5LXvUjrIQcZvNyANNEyFrd2YGs196PniNT1fgvOQA==
|
||||
dependencies:
|
||||
"@types/cheerio" "*"
|
||||
@@ -13280,7 +13280,7 @@ cached-path-relative@^1.0.0, cached-path-relative@^1.0.2:
|
||||
resolved "https://registry.yarnpkg.com/cached-path-relative/-/cached-path-relative-1.0.2.tgz#a13df4196d26776220cc3356eb147a52dba2c6db"
|
||||
integrity sha512-5r2GqsoEb4qMTTN9J+WzXfjov+hjxT+j3u5K+kIVNIwAd99DLCJE9pBIMP1qVeybV6JiijL385Oz0DcYxfbOIg==
|
||||
|
||||
cachedir@^2.3.0:
|
||||
cachedir@2.3.0, cachedir@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.3.0.tgz#0c75892a052198f0b21c7c1804d8331edfcae0e8"
|
||||
integrity sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==
|
||||
@@ -20675,7 +20675,7 @@ glob@7.1.3:
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
glob@7.1.6, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
|
||||
glob@7.1.6:
|
||||
version "7.1.6"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
|
||||
integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
|
||||
@@ -20687,6 +20687,18 @@ glob@7.1.6, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.0, glo
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
glob@7.2.0, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
|
||||
version "7.2.0"
|
||||
resolved "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023"
|
||||
integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==
|
||||
dependencies:
|
||||
fs.realpath "^1.0.0"
|
||||
inflight "^1.0.4"
|
||||
inherits "2"
|
||||
minimatch "^3.0.4"
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
glob@^5.0.15:
|
||||
version "5.0.15"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1"
|
||||
@@ -31713,7 +31725,7 @@ pretty-error@^2.0.2, pretty-error@^2.1.1:
|
||||
|
||||
pretty-format@26.4.0, pretty-format@^24.9.0, pretty-format@^26.6.2:
|
||||
version "26.4.0"
|
||||
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.4.0.tgz#c08073f531429e9e5024049446f42ecc9f933a3b"
|
||||
resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-26.4.0.tgz#c08073f531429e9e5024049446f42ecc9f933a3b"
|
||||
integrity sha512-mEEwwpCseqrUtuMbrJG4b824877pM5xald3AkilJ47Po2YLr97/siejYQHqj2oDQBeJNbu+Q0qUuekJ8F0NAPg==
|
||||
dependencies:
|
||||
"@jest/types" "^26.3.0"
|
||||
@@ -35853,7 +35865,7 @@ socket.io-client@4.0.1:
|
||||
|
||||
socket.io-parser@4.0.4, socket.io-parser@~3.3.0, socket.io-parser@~3.4.0, socket.io-parser@~4.0.3, socket.io-parser@~4.0.4:
|
||||
version "4.0.4"
|
||||
resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.0.4.tgz#9ea21b0d61508d18196ef04a2c6b9ab630f4c2b0"
|
||||
resolved "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz#9ea21b0d61508d18196ef04a2c6b9ab630f4c2b0"
|
||||
integrity sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==
|
||||
dependencies:
|
||||
"@types/component-emitter" "^1.2.10"
|
||||
@@ -38501,7 +38513,7 @@ typescript@^4.2.3, typescript@^4.4.4:
|
||||
|
||||
ua-parser-js@0.7.24, ua-parser-js@^0.7.18:
|
||||
version "0.7.24"
|
||||
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.24.tgz#8d3ecea46ed4f1f1d63ec25f17d8568105dc027c"
|
||||
resolved "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.24.tgz#8d3ecea46ed4f1f1d63ec25f17d8568105dc027c"
|
||||
integrity sha512-yo+miGzQx5gakzVK3QFfN0/L9uVhosXBBO7qmnk7c2iw1IhL212wfA3zbnI54B0obGwC/5NWub/iT9sReMx+Fw==
|
||||
|
||||
uc.micro@^1.0.1, uc.micro@^1.0.5:
|
||||
@@ -39942,7 +39954,7 @@ vue-style-loader@^4.1.0, vue-style-loader@^4.1.2:
|
||||
|
||||
vue-template-compiler@2.6.12, vue-template-compiler@^2.6.11:
|
||||
version "2.6.12"
|
||||
resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.6.12.tgz#947ed7196744c8a5285ebe1233fe960437fcc57e"
|
||||
resolved "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.12.tgz#947ed7196744c8a5285ebe1233fe960437fcc57e"
|
||||
integrity sha512-OzzZ52zS41YUbkCBfdXShQTe69j1gQDZ9HIX8miuC9C3rBCk9wIRjLiZZLrmX9V+Ftq/YEyv1JaVr5Y/hNtByg==
|
||||
dependencies:
|
||||
de-indent "^1.0.2"
|
||||
|
||||
Reference in New Issue
Block a user