mirror of
https://github.com/cypress-io/cypress.git
synced 2026-05-04 14:00:22 -05:00
Merge branch 'develop' into feature-multidomain
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
* text=auto
|
||||
|
||||
*.json text eol=lf
|
||||
|
||||
packages/errors/__snapshot-html__/** linguist-generated=true
|
||||
@@ -1,2 +0,0 @@
|
||||
# Always validate the PR title, and ignore the commits
|
||||
titleOnly: true
|
||||
@@ -0,0 +1,21 @@
|
||||
name: "Semantic Pull Request"
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- opened
|
||||
- edited
|
||||
- synchronize
|
||||
|
||||
jobs:
|
||||
main:
|
||||
name: Lint Title
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# use a fork of the GitHub action - we cannot pull in untrusted third party actions
|
||||
# see https://github.com/cypress-io/cypress/pull/20091#discussion_r801799647
|
||||
- uses: cypress-io/action-semantic-pull-request@v4
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
validateSingleCommit: true
|
||||
@@ -18,6 +18,8 @@ packages/config/lib/*.js
|
||||
|
||||
# from data-context, compiled .js files
|
||||
packages/data-context/src/**/*.js
|
||||
packages/errors/src/**/*.js
|
||||
packages/errors/test/**/*.js
|
||||
|
||||
# from desktop-gui
|
||||
packages/desktop-gui/cypress/videos
|
||||
@@ -68,6 +70,7 @@ packages/socket/lib/*.js
|
||||
|
||||
# from system-tests
|
||||
system-tests/.projects
|
||||
system-tests/.http-mitm-proxy
|
||||
system-tests/fixtures/large-img
|
||||
|
||||
# from npm/react
|
||||
@@ -83,6 +86,11 @@ system-tests/fixtures/large-img
|
||||
# from runner-ct
|
||||
/packages/runner-ct/cypress/screenshots
|
||||
|
||||
# from errors
|
||||
/packages/errors/__snapshot-images__
|
||||
/packages/errors/__snapshot-md__
|
||||
/packages/errors/__snapshot-html-local__
|
||||
|
||||
# graphql, auto-generated
|
||||
/packages/launchpad/src/generated
|
||||
/packages/app/src/generated
|
||||
|
||||
Vendored
+2
-2
@@ -36,6 +36,6 @@
|
||||
"i18n-ally.keystyle": "nested",
|
||||
|
||||
// Volar is the main extension that powers Vue's language features.
|
||||
"volar.autoCompleteRefs": false,
|
||||
"volar.takeOverMode.enabled": true
|
||||
// "volar.autoCompleteRefs": false,
|
||||
"volar.takeOverMode.enabled": true,
|
||||
}
|
||||
|
||||
@@ -1,19 +1,9 @@
|
||||
exports['list of all projects'] = [
|
||||
{
|
||||
"repo": "cypress-io/cypress-test-tiny",
|
||||
"provider": "circle",
|
||||
"platform": "win32"
|
||||
},
|
||||
{
|
||||
"repo": "cypress-io/cypress-test-example-repos",
|
||||
"provider": "circle",
|
||||
"platform": "win32"
|
||||
},
|
||||
{
|
||||
"repo": "cypress-io/cypress-test-tiny",
|
||||
"provider": "circle",
|
||||
"platform": "linux"
|
||||
},
|
||||
{
|
||||
"repo": "cypress-io/cypress-test-module-api",
|
||||
"provider": "circle",
|
||||
@@ -24,11 +14,6 @@ exports['list of all projects'] = [
|
||||
"provider": "circle",
|
||||
"platform": "linux"
|
||||
},
|
||||
{
|
||||
"repo": "cypress-io/cypress-test-nested-projects",
|
||||
"provider": "circle",
|
||||
"platform": "linux"
|
||||
},
|
||||
{
|
||||
"repo": "cypress-io/cypress-test-ci-environments",
|
||||
"provider": "circle",
|
||||
@@ -39,11 +24,6 @@ exports['list of all projects'] = [
|
||||
"provider": "circle",
|
||||
"platform": "linux"
|
||||
},
|
||||
{
|
||||
"repo": "cypress-io/cypress-test-tiny",
|
||||
"provider": "circle",
|
||||
"platform": "darwin"
|
||||
},
|
||||
{
|
||||
"repo": "cypress-io/cypress-test-example-repos",
|
||||
"provider": "circle",
|
||||
@@ -52,11 +32,6 @@ exports['list of all projects'] = [
|
||||
]
|
||||
|
||||
exports['should have just circle and darwin projects'] = [
|
||||
{
|
||||
"repo": "cypress-io/cypress-test-tiny",
|
||||
"provider": "circle",
|
||||
"platform": "darwin"
|
||||
},
|
||||
{
|
||||
"repo": "cypress-io/cypress-test-example-repos",
|
||||
"provider": "circle",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"chrome:beta": "98.0.4758.80",
|
||||
"chrome:beta": "99.0.4844.27",
|
||||
"chrome:stable": "98.0.4758.80"
|
||||
}
|
||||
|
||||
+9
-86
@@ -89,7 +89,7 @@ executors:
|
||||
# https://github.com/CircleCI-Public/windows-orb/blob/master/src/executors/default.yml
|
||||
# https://circleci.com/docs/2.0/hello-world-windows/#software-pre-installed-in-the-windows-image
|
||||
windows: &windows-executor
|
||||
machine:
|
||||
machine:
|
||||
image: windows-server-2019-vs2019:stable
|
||||
shell: bash.exe -eo pipefail
|
||||
resource_class: windows.medium
|
||||
@@ -151,7 +151,7 @@ commands:
|
||||
- cypress
|
||||
- .ssh
|
||||
- node_modules # contains the npm i -g modules
|
||||
|
||||
|
||||
install_cache_helpers_dependencies:
|
||||
steps:
|
||||
- run:
|
||||
@@ -987,6 +987,7 @@ jobs:
|
||||
- run:
|
||||
name: Linting 🧹
|
||||
command: |
|
||||
yarn clean
|
||||
git clean -df
|
||||
yarn lint
|
||||
- run:
|
||||
@@ -1075,12 +1076,14 @@ jobs:
|
||||
# run unit tests from each individual package
|
||||
- run: yarn test
|
||||
- verify-mocha-results:
|
||||
expectedResultCount: 9
|
||||
expectedResultCount: 10
|
||||
- store_test_results:
|
||||
path: /tmp/cypress
|
||||
# CLI tests generate HTML files with sample CLI command output
|
||||
- store_artifacts:
|
||||
path: cli/test/html
|
||||
- store_artifacts:
|
||||
path: packages/errors/__snapshot-images__
|
||||
- store-npm-logs
|
||||
|
||||
unit-tests-release:
|
||||
@@ -1913,13 +1916,6 @@ jobs:
|
||||
repo: cypress-example-kitchensink
|
||||
browser: "electron"
|
||||
|
||||
test-binary-against-awesome-typescript-loader:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- test-binary-against-repo:
|
||||
repo: cypress-test-awesome-typescript-loader
|
||||
browser: "electron"
|
||||
|
||||
test-binary-against-kitchensink-firefox:
|
||||
<<: *defaults
|
||||
resource_class: medium
|
||||
@@ -1944,33 +1940,6 @@ jobs:
|
||||
repo: cypress-example-todomvc
|
||||
browser: firefox
|
||||
|
||||
test-binary-against-conduit-chrome:
|
||||
<<: *defaults
|
||||
resource_class: medium
|
||||
steps:
|
||||
- test-binary-against-repo:
|
||||
repo: cypress-example-conduit-app
|
||||
browser: chrome
|
||||
command: "npm run cypress:run"
|
||||
wait-on: http://localhost:3000
|
||||
|
||||
test-binary-against-api-testing-firefox:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- test-binary-against-repo:
|
||||
repo: cypress-example-api-testing
|
||||
browser: firefox
|
||||
command: "npm run cy:run"
|
||||
|
||||
test-binary-against-piechopper-firefox:
|
||||
<<: *defaults
|
||||
resource_class: medium
|
||||
steps:
|
||||
- test-binary-against-repo:
|
||||
repo: cypress-example-piechopper
|
||||
browser: firefox
|
||||
command: "npm run cypress:run"
|
||||
|
||||
test-binary-against-cypress-realworld-app:
|
||||
<<: *defaults
|
||||
resource_class: medium+
|
||||
@@ -2239,26 +2208,6 @@ linux-workflow: &linux-workflow
|
||||
- test-binary-against-kitchensink:
|
||||
requires:
|
||||
- create-build-artifacts
|
||||
# when working on a feature or a fix,
|
||||
# you are probably working in a branch
|
||||
# and you want to run a specific PR in the cypress-example-recipes
|
||||
# against this branch. This workflow job includes
|
||||
# the job but only when it runs on specific branch
|
||||
# DO NOT DELETE THIS JOB BEFORE MERGING TO DEVELOP
|
||||
# on "develop" this branch will be ignored anyway
|
||||
# and someone else might use this job definition for another
|
||||
# feature branch and would just update the branch filter
|
||||
# - test-binary-against-recipe-pull-request:
|
||||
# name: Test cypress run parsing
|
||||
# filters:
|
||||
# branches:
|
||||
# only:
|
||||
# - cli-to-module-api-7760
|
||||
# requires:
|
||||
# - create-build-artifacts
|
||||
- test-binary-against-awesome-typescript-loader:
|
||||
requires:
|
||||
- create-build-artifacts
|
||||
- test-binary-and-npm-against-other-projects:
|
||||
context: test-runner:trigger-test-jobs
|
||||
<<: *mainBuildFilters
|
||||
@@ -2278,12 +2227,7 @@ linux-workflow: &linux-workflow
|
||||
<<: *mainBuildFilters
|
||||
requires:
|
||||
- create-build-artifacts
|
||||
# Re-enable when the cypress-example-conduit-app project is fixed.
|
||||
# https://github.com/cypress-io/cypress-example-conduit-app/issues/346
|
||||
# - test-binary-against-conduit-chrome:
|
||||
# <<: *mainBuildFilters
|
||||
# requires:
|
||||
# - create-build-artifacts
|
||||
|
||||
- test-binary-against-recipes-firefox:
|
||||
<<: *mainBuildFilters
|
||||
requires:
|
||||
@@ -2296,14 +2240,6 @@ linux-workflow: &linux-workflow
|
||||
<<: *mainBuildFilters
|
||||
requires:
|
||||
- create-build-artifacts
|
||||
- test-binary-against-api-testing-firefox:
|
||||
<<: *mainBuildFilters
|
||||
requires:
|
||||
- create-build-artifacts
|
||||
- test-binary-against-piechopper-firefox:
|
||||
<<: *mainBuildFilters
|
||||
requires:
|
||||
- create-build-artifacts
|
||||
- test-binary-against-cypress-realworld-app:
|
||||
<<: *mainBuildFilters
|
||||
requires:
|
||||
@@ -2359,19 +2295,6 @@ mac-workflow: &mac-workflow
|
||||
requires:
|
||||
- darwin-build
|
||||
|
||||
- test-binary-against-kitchensink:
|
||||
name: darwin-test-binary-against-kitchensink
|
||||
executor: mac
|
||||
requires:
|
||||
- darwin-create-build-artifacts
|
||||
|
||||
- test-binary-against-staging:
|
||||
context: test-runner:record-tests
|
||||
name: darwin-test-binary-against-staging
|
||||
executor: mac
|
||||
requires:
|
||||
- darwin-create-build-artifacts
|
||||
|
||||
- test-binary-and-npm-against-other-projects:
|
||||
context: test-runner:trigger-test-jobs
|
||||
name: darwin-test-binary-and-npm-against-other-projects
|
||||
@@ -2399,14 +2322,14 @@ windows-workflow: &windows-workflow
|
||||
executor: windows
|
||||
requires:
|
||||
- windows-build
|
||||
|
||||
|
||||
- unit-tests:
|
||||
name: windows-unit-tests
|
||||
executor: windows
|
||||
resource_class: windows.medium
|
||||
requires:
|
||||
- windows-build
|
||||
|
||||
|
||||
- create-build-artifacts:
|
||||
name: windows-create-build-artifacts
|
||||
executor: windows
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
## Error Handling in Cypress
|
||||
|
||||
Clear, consistent, errors are one of the important parts of the Cypress experience. When something goes wrong, there should be clear, actionable feedback for the user about exactly *what* went wrong, *where* it went wrong, and next steps on how to fix.
|
||||
|
||||
### @packages/errors
|
||||
|
||||
All error related logic for the server should be added to `@packages/errors`. This logic has been separated out from the `@packages/server` to enable strict type checking & use in other packages we have added in the `10.0-release` branch.
|
||||
|
||||
Summary of the Errors package:
|
||||
|
||||
- `errors.ts`: A key/value mapping of known errors to functions returning "ErrorTemplates", described below, also includes/re-exports several helper utilities:
|
||||
- `get` / `getError`: builds & retrieves the error as a `CypressError`, should be the main way we retrieve errors throughout Cypress. Aliased as `errors.get` for existing use in the server package
|
||||
- `throw` / `throwErr`: Get & throw the error, so we can spy/stub it in a test. Aliased as `errors.throw` for existing use in the server package
|
||||
- `logWarning`: Logs the error as a warning to the console, aliased as `errors.log` for existing use in the server package
|
||||
- `errTemplate.ts`: Tagged template literal formatting the error as described below
|
||||
- `stackUtils.ts`: Utilities for working with a stack trace, extended by the driver package
|
||||
|
||||
### errTemplate
|
||||
|
||||
The `errTemplate` is a tagged template literal. It allows us to maintain consistent behavior & formatting in our error messages, when we see a variable, we format it depending on the target environment.
|
||||
|
||||
The error message returns a message that defaults to being formatted for the terminal, and has a `forBrowser` method which returns the error message where the variables are wrapped in backticks '`' for Markdown display in the browser.
|
||||
|
||||
Return Value of `errTemplate` (`ErrTemplateResult`):
|
||||
|
||||
```ts
|
||||
{
|
||||
// Will always exist, this is the terminal-formatted error message
|
||||
message: string,
|
||||
// Will always exist, this is the browser-formatted error message
|
||||
messageMarkdown: string,
|
||||
details?: string, // Exists if there is `details()` call in the errTemplate
|
||||
originalError?: ErrorLike // Exists if an error was passed into the `details()`
|
||||
}
|
||||
```
|
||||
|
||||
#### Example:
|
||||
|
||||
```ts
|
||||
CANNOT_TRASH_ASSETS: (arg1: string) => {
|
||||
return errTemplate`\
|
||||
Warning: We failed to trash the existing run results.
|
||||
|
||||
This error will not alter the exit code.
|
||||
|
||||
${details(arg1)}`
|
||||
},
|
||||
```
|
||||
|
||||
In this case, `arg1` will be highlighted in yellow when printed to the terminal.
|
||||
|
||||
|
||||
```ts
|
||||
PLUGINS_FILE_ERROR: (arg1: string, arg2: Error) => {
|
||||
return errTemplate`\
|
||||
The plugins file is missing or invalid.
|
||||
|
||||
Your \`pluginsFile\` is set to ${arg1}, but either the file is missing, it contains a syntax error, or threw an error when required. The \`pluginsFile\` must be a \`.js\`, \`.ts\`, or \`.coffee\` file.
|
||||
|
||||
Or you might have renamed the extension of your \`pluginsFile\`. If that's the case, restart the test runner.
|
||||
|
||||
Please fix this, or set \`pluginsFile\` to \`false\` if a plugins file is not necessary for your project.
|
||||
|
||||
${details(arg2)}
|
||||
`
|
||||
},
|
||||
```
|
||||
|
||||
`arg1` will be highlighted in `blue` for the terminal, and wrapped in backticks when called with `forBrowser`. Details will be printed in `yellow` as a stack trace when printed to the terminal, or shown as a stack-trace in the browser.
|
||||
|
||||
### Error Wrapping
|
||||
|
||||
Any time we know about an edge case that is an error, we should define an error in `errors.ts`. This error should be retrieved by `getError`, which converts it to a `CypressError`.
|
||||
|
||||
The `CypressError` is an `Error` containing the message returned from the `errTemplate`. The `stack` is set to that of the `originalError` if it exists (i.e. the error object passed into `details`), otherwise it's the `stack` from where the `getError` / `throwError` is called.
|
||||
|
||||
|
||||
The `CypressError` has an `isCypressErr` prop which we use as a duck-type guard against exiting the process when logging exceptions. It also maintains a reference to the `originalError` if it exists.
|
||||
|
||||
### Child-Process Errors
|
||||
|
||||
All errors that occur in a child process spawned by Cypress should be sent over the `ipc` bridge using `util.serializeError`.
|
||||
|
||||
This ensures the `name`, `message`, `stack`, and any other relevant details are preserved and can be handled by the standard process of Cypress' error standardization / wrapping.
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
# [@cypress/react-v5.12.2](https://github.com/cypress-io/cypress/compare/@cypress/react-v5.12.1...@cypress/react-v5.12.2) (2022-02-08)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* remove nullish coalescing in js files to support node 12 ([#20094](https://github.com/cypress-io/cypress/issues/20094)) ([dd11945](https://github.com/cypress-io/cypress/commit/dd11945f5330c14e1540133187415f341794d6f6))
|
||||
|
||||
# [@cypress/react-v5.12.1](https://github.com/cypress-io/cypress/compare/@cypress/react-v5.12.0...@cypress/react-v5.12.1) (2022-01-10)
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
const path = require('path')
|
||||
|
||||
function getTranspileFolders (config) {
|
||||
const rawFolders = config.addTranspiledFolders ?? []
|
||||
const rawFolders = config.addTranspiledFolders || []
|
||||
const folders = rawFolders.map((folder) => path.resolve(config.projectRoot, folder))
|
||||
|
||||
// user can disable folders, so check first
|
||||
|
||||
@@ -56,8 +56,8 @@ Install `@cypress/vue` or `@cypress/react` to get this package working properly
|
||||
- The HTML page calls a script that loads support file and the specs using a native `import()` function
|
||||
- Then triggers the loaded tests
|
||||
|
||||
Vite is reponsible for compiling and bundling all the files. We use its error overlay to display any transpiling error.
|
||||
Omly runtime errors have to be handled through cypress
|
||||
Vite is responsible for compiling and bundling all the files. We use its error overlay to display any transpiling error.
|
||||
Only runtime errors have to be handled through cypress
|
||||
|
||||
## Changelog
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
// This file is merged in a <script type=module> into index.html
|
||||
// it will be used to load and kick start the selected spec
|
||||
|
||||
const supportPath = import.meta.env.__cypress_supportPath
|
||||
const originAutUrl = import.meta.env.__cypress_originAutUrl
|
||||
import specLoaders from 'cypress:spec-loaders'
|
||||
import { hasSupportPath, originAutUrl } from 'cypress:config'
|
||||
|
||||
const specPath = window.location.pathname.replace(originAutUrl, '')
|
||||
|
||||
const importsToLoad = [() => import(/* @vite-ignore */ specPath)]
|
||||
const specLoader = specLoaders[specPath]
|
||||
const importsToLoad = [specLoader || (() => import(/* @vite-ignore */ specPath))]
|
||||
|
||||
if (supportPath) {
|
||||
importsToLoad.unshift(() => import(/* @vite-ignore */ supportPath))
|
||||
if (hasSupportPath) {
|
||||
importsToLoad.unshift(() => import('cypress:support-path'))
|
||||
}
|
||||
|
||||
const CypressInstance = window.Cypress = parent.Cypress
|
||||
@@ -46,3 +46,4 @@ CypressInstance.on('test:before:run', () => {
|
||||
|
||||
// Make usage of node test plugins possible
|
||||
window.global = window
|
||||
window.process = typeof process !== 'undefined' ? process : {}
|
||||
|
||||
@@ -1,19 +1,27 @@
|
||||
import { debug as debugFn } from 'debug'
|
||||
import { InlineConfig } from 'vite'
|
||||
import { start as createDevServer, StartDevServerOptions } from './startServer'
|
||||
import { createServer, InlineConfig } from 'vite'
|
||||
import { resolveServerConfig, StartDevServerOptions } from './resolveServerConfig'
|
||||
const debug = debugFn('cypress:vite-dev-server:vite')
|
||||
|
||||
export { StartDevServerOptions }
|
||||
|
||||
export async function startDevServer (startDevServerArgs: StartDevServerOptions): Promise<Cypress.ResolvedDevServerConfig> {
|
||||
const viteDevServer = await createDevServer(startDevServerArgs)
|
||||
if (!startDevServerArgs.viteConfig) {
|
||||
debug('User did not pass in any Vite dev server configuration')
|
||||
startDevServerArgs.viteConfig = {}
|
||||
}
|
||||
|
||||
const app = await viteDevServer.listen()
|
||||
const port = app.config.server.port!
|
||||
debug('starting vite dev server')
|
||||
const resolvedConfig = await resolveServerConfig(startDevServerArgs)
|
||||
const port = resolvedConfig.server!.port!
|
||||
|
||||
const viteDevServer = await createServer(resolvedConfig)
|
||||
|
||||
await viteDevServer.listen()
|
||||
|
||||
debug('Component testing vite server started on port', port)
|
||||
|
||||
return { port, close: app.httpServer!.close }
|
||||
return { port, close: viteDevServer.close }
|
||||
}
|
||||
|
||||
export type CypressViteDevServerConfig = Omit<InlineConfig, 'base' | 'root'>
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
import { resolve, sep } from 'path'
|
||||
import { readFile } from 'fs'
|
||||
import { promisify } from 'util'
|
||||
import { readFile } from 'fs/promises'
|
||||
import Debug from 'debug'
|
||||
import { ModuleNode, Plugin, ViteDevServer } from 'vite'
|
||||
import { ModuleNode, normalizePath, Plugin, ViteDevServer } from 'vite'
|
||||
|
||||
const debug = Debug('cypress:vite-dev-server:plugin')
|
||||
|
||||
const read = promisify(readFile)
|
||||
|
||||
const pluginName = 'cypress-transform-html'
|
||||
const OSSepRE = new RegExp(`\\${sep}`, 'g')
|
||||
|
||||
@@ -48,40 +45,56 @@ export const makeCypressPlugin = (
|
||||
|
||||
const posixSupportFilePath = supportFilePath ? convertPathToPosix(resolve(projectRoot, supportFilePath)) : undefined
|
||||
|
||||
const normalizedSupportFilePath = posixSupportFilePath ? `${base}@fs/${posixSupportFilePath}` : undefined
|
||||
|
||||
return {
|
||||
name: pluginName,
|
||||
enforce: 'pre',
|
||||
config (_, env) {
|
||||
if (env) {
|
||||
return {
|
||||
define: {
|
||||
'import.meta.env.__cypress_supportPath': JSON.stringify(normalizedSupportFilePath),
|
||||
'import.meta.env.__cypress_originAutUrl': JSON.stringify(`__cypress/iframes/${convertPathToPosix(projectRoot)}/`),
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
configResolved (config) {
|
||||
base = config.base
|
||||
},
|
||||
transformIndexHtml () {
|
||||
debug('transformIndexHtml with base', base)
|
||||
async transformIndexHtml () {
|
||||
const indexHtmlPath = resolve(__dirname, '..', 'index.html')
|
||||
const indexHtmlContent = await readFile(indexHtmlPath, { encoding: 'utf8' })
|
||||
// find </body> last index
|
||||
const endOfBody = indexHtmlContent.lastIndexOf('</body>')
|
||||
|
||||
return [
|
||||
// load the script at the end of the body
|
||||
// script has to be loaded when the vite client is connected
|
||||
{
|
||||
tag: 'script',
|
||||
injectTo: 'body',
|
||||
attrs: { type: 'module' },
|
||||
children: `import(${JSON.stringify(`${base}@fs/${INIT_FILEPATH}`)})`,
|
||||
},
|
||||
]
|
||||
// insert the script in the end of the body
|
||||
return `${indexHtmlContent.substring(0, endOfBody)
|
||||
}<script src="${base}cypress:client-init-test" type="module"></script>${
|
||||
indexHtmlContent.substring(endOfBody)
|
||||
}`
|
||||
},
|
||||
resolveId (id) {
|
||||
if (id === 'cypress:config') {
|
||||
return id
|
||||
}
|
||||
|
||||
if (id === 'cypress:support-path') {
|
||||
return posixSupportFilePath
|
||||
}
|
||||
|
||||
if (id === 'cypress:spec-loaders') {
|
||||
return id
|
||||
}
|
||||
|
||||
if (id === '/cypress:client-init-test') {
|
||||
return INIT_FILEPATH
|
||||
}
|
||||
},
|
||||
load (id) {
|
||||
if (id === 'cypress:spec-loaders') {
|
||||
return `export default {\n${specs.map((s) => {
|
||||
return `${JSON.stringify(s.relative)}:()=>import(${JSON.stringify(s.absolute)})`
|
||||
}).join(',\n')}\n}`
|
||||
}
|
||||
|
||||
if (id === 'cypress:config') {
|
||||
return `
|
||||
export const hasSupportPath = ${JSON.stringify(!!supportFilePath)}
|
||||
export const originAutUrl = ${JSON.stringify(`/__cypress/iframes/${normalizePath(projectRoot)}/`)}`
|
||||
}
|
||||
},
|
||||
configureServer: async (server: ViteDevServer) => {
|
||||
const indexHtml = await read(resolve(__dirname, '..', 'index.html'), { encoding: 'utf8' })
|
||||
const indexHtml = await readFile(resolve(__dirname, '..', 'index.html'), { encoding: 'utf8' })
|
||||
|
||||
const transformedIndexHtml = await server.transformIndexHtml(base, indexHtml)
|
||||
|
||||
|
||||
+1
-13
@@ -20,7 +20,7 @@ export interface StartDevServerOptions {
|
||||
viteConfig?: Omit<InlineConfig, 'base' | 'root'>
|
||||
}
|
||||
|
||||
const resolveServerConfig = async ({ viteConfig, options }: StartDevServerOptions): Promise<InlineConfig> => {
|
||||
export const resolveServerConfig = async ({ viteConfig, options }: StartDevServerOptions): Promise<InlineConfig> => {
|
||||
const { projectRoot, supportFile } = options.config
|
||||
|
||||
const requiredOptions: InlineConfig = {
|
||||
@@ -74,15 +74,3 @@ const resolveServerConfig = async ({ viteConfig, options }: StartDevServerOption
|
||||
|
||||
return finalConfig
|
||||
}
|
||||
|
||||
export async function start (devServerOptions: StartDevServerOptions): Promise<ViteDevServer> {
|
||||
if (!devServerOptions.viteConfig) {
|
||||
debug('User did not pass in any Vite dev server configuration')
|
||||
devServerOptions.viteConfig = {}
|
||||
}
|
||||
|
||||
debug('starting vite dev server')
|
||||
const resolvedConfig = await resolveServerConfig(devServerOptions)
|
||||
|
||||
return createServer(resolvedConfig)
|
||||
}
|
||||
@@ -1,12 +1,9 @@
|
||||
module.exports = {
|
||||
...require('../../.releaserc.base'),
|
||||
branches: [
|
||||
// we need to keep this branch in here even if no used because semantic-release demands
|
||||
// that we have at least one branch that has no config
|
||||
'next/npm/vue',
|
||||
// this line forces releasing 2.X releases on the latest channel
|
||||
{ name: 'npm/vue/v2', range: '2.X.X' },
|
||||
// this one releases v3 on master as beta on the next channel
|
||||
{ name: 'master', channel: 'next' },
|
||||
// this one releases v3 on master on the latest channel
|
||||
'master',
|
||||
// this line forces releasing 2.X releases on the v2 channel
|
||||
{ name: 'npm/vue/v2', range: '2.X.X', channel: 'v2' },
|
||||
],
|
||||
}
|
||||
|
||||
+2
-17
@@ -24,7 +24,7 @@ It uses [Vue Test Utils](https://github.com/vuejs/vue-test-utils) under the hood
|
||||
|
||||
- Requires Cypress v7.0.0 or later
|
||||
- Requires [Node](https://nodejs.org/en/) version 12 or above
|
||||
- Supports webpack-based projects, vite in alpha, if you would like us to support another, please [create an issue](https://github.com/cypress-io/cypress/issues/new?assignees=&labels=npm:%20@cypress/vue&template=3-feature.md) or, if an issue already exists subscribe to it.
|
||||
- Supports projects built with Vue CLI, Vite, and Webpack. If you would like us to support another build configuration, please [create an issue](https://github.com/cypress-io/cypress/issues/new?assignees=&labels=npm:%20@cypress/vue&template=3-feature.md).
|
||||
|
||||
Now you are ready to install.
|
||||
|
||||
@@ -61,8 +61,7 @@ module.exports = (on) => {
|
||||
Install dev dependencies
|
||||
|
||||
```shell
|
||||
npm i -D @cypress/webpack-dev-server \
|
||||
vue-loader vue-template-compiler css-loader
|
||||
npm i -D @cypress/webpack-dev-server @cypress/vue
|
||||
```
|
||||
|
||||
And write a test
|
||||
@@ -617,20 +616,6 @@ yarn workspace @cypress/vue cy:open
|
||||
|
||||
Larger tests that use full application and run on CI (see [circle.yml](circle.yml)) are located in the folder [examples](examples).
|
||||
|
||||
### Debugging
|
||||
|
||||
Run Cypress with environment variable
|
||||
|
||||
```
|
||||
DEBUG=@cypress/vue
|
||||
```
|
||||
|
||||
If some deeply nested objects are abbreviated and do not print fully, set the maximum logging depth
|
||||
|
||||
```
|
||||
DEBUG=@cypress/vue DEBUG_DEPTH=10
|
||||
```
|
||||
|
||||
## Related info
|
||||
|
||||
- [Testing Vue web applications with Vuex data store & REST backend](https://www.cypress.io/blog/2017/11/28/testing-vue-web-application-with-vuex-data-store-and-rest-backend/)
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
# [@cypress/webpack-dev-server-v1.8.1](https://github.com/cypress-io/cypress/compare/@cypress/webpack-dev-server-v1.8.0...@cypress/webpack-dev-server-v1.8.1) (2022-02-08)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* detect newly added specs in dev-server compilation ([#17950](https://github.com/cypress-io/cypress/issues/17950)) ([f9ce67c](https://github.com/cypress-io/cypress/commit/f9ce67cfb6fed74a3549e7aff7ce0a5b217d9a13))
|
||||
|
||||
# [@cypress/webpack-dev-server-v1.8.0](https://github.com/cypress-io/cypress/compare/@cypress/webpack-dev-server-v1.7.0...@cypress/webpack-dev-server-v1.8.0) (2021-12-16)
|
||||
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"build-prod": "tsc",
|
||||
"test": "node ./test-wds-3.js",
|
||||
"test": "node ./test-deps.js",
|
||||
"test-all": "tsc && mocha -r @packages/ts/register test/**/*.spec.ts test/*.spec.ts --exit",
|
||||
"watch": "tsc -w"
|
||||
},
|
||||
|
||||
@@ -20,6 +20,7 @@ export async function startDevServer (startDevServerArgs: StartDevServer, exitPr
|
||||
|
||||
return new Promise<ResolvedDevServerConfig>(async (resolve, reject) => {
|
||||
if (webpackDevServerFacts.isV3()) {
|
||||
// @ts-ignore
|
||||
const server: Server = webpackDevServer.listen(0, '127.0.0.1', () => {
|
||||
// FIXME: handle address returning a string
|
||||
const port = (server.address() as AddressInfo).port
|
||||
|
||||
@@ -5,6 +5,7 @@ import debugFn from 'debug'
|
||||
import * as path from 'path'
|
||||
import { CypressCTWebpackContext } from './plugin'
|
||||
const debug = debugFn('cypress:webpack-dev-server:webpack')
|
||||
import type { LoaderContext } from 'webpack'
|
||||
|
||||
/**
|
||||
* @param {ComponentSpec} file spec to create import string from.
|
||||
@@ -49,7 +50,11 @@ function buildSpecs (projectRoot: string, files: Cypress.Cypress['spec'][] = [])
|
||||
}
|
||||
|
||||
// Runs the tests inside the iframe
|
||||
export default function loader (this: CypressCTWebpackContext) {
|
||||
export default function loader (this: CypressCTWebpackContext & LoaderContext<void>) {
|
||||
// In Webpack 5, a spec added after the dev-server is created won't
|
||||
// be included in the compilation. Disabling the caching of this loader ensures
|
||||
// we regenerate our specs and include any new ones in the compilation.
|
||||
this.cacheable(false)
|
||||
const { files, projectRoot, supportFile } = this._cypress
|
||||
|
||||
const supportFileAbsolutePath = supportFile ? JSON.stringify(path.resolve(projectRoot, supportFile)) : undefined
|
||||
|
||||
@@ -83,7 +83,7 @@ export async function start ({ webpackConfig: userWebpackConfig, template, optio
|
||||
hot: false,
|
||||
}
|
||||
|
||||
// @ts-expect-error Webpack types are clashing between Webpack and WebpackDevServer
|
||||
// @ts-ignore Webpack types are clashing between Webpack and WebpackDevServer
|
||||
return new WebpackDevServer(webpackDevServerConfig, compiler)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
const execa = require('execa')
|
||||
const pkg = require('./package.json')
|
||||
const fs = require('fs')
|
||||
|
||||
/**
|
||||
* This file installs dependencies that we support but don't have coverage for.
|
||||
* We read package.json, update the dependency, then re-run yarn install.
|
||||
* After it finishes, pass or fail,
|
||||
* we revert the package.json back to the original state.
|
||||
*/
|
||||
const main = async () => {
|
||||
const depsToTest = [
|
||||
[
|
||||
{
|
||||
name: 'webpack-dev-server',
|
||||
version: '3.11.0',
|
||||
type: 'devDependencies',
|
||||
},
|
||||
],
|
||||
[
|
||||
{ name: 'webpack', version: '5.53.0', type: 'devDependencies' },
|
||||
{
|
||||
name: 'html-webpack-plugin',
|
||||
version: '5.3.2',
|
||||
type: 'devDependencies',
|
||||
},
|
||||
],
|
||||
]
|
||||
const originalPkg = JSON.stringify(pkg, null, 2)
|
||||
|
||||
const install = () => execa('yarn', ['install', '--ignore-scripts'], { stdio: 'inherit' })
|
||||
|
||||
const exit = async (exitCode) => {
|
||||
fs.writeFileSync('package.json', originalPkg, 'utf8')
|
||||
await install()
|
||||
process.exit(exitCode)
|
||||
}
|
||||
|
||||
for (const deps of depsToTest) {
|
||||
const pkg = JSON.parse(originalPkg)
|
||||
const depsInfo = JSON.stringify(deps)
|
||||
|
||||
deps.forEach(({ type, name, version }) => (pkg[type][name] = version))
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('[@cypress/webpack-dev-server]: updating package.json...')
|
||||
fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2), 'utf8')
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('[@cypress/webpack-dev-server]: install dependencies...')
|
||||
await install()
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(
|
||||
`[@cypress/webpack-dev-server]: Testing with deps: ${depsInfo}`,
|
||||
)
|
||||
|
||||
const { exitCode } = await execa('yarn', ['test-all'], {
|
||||
stdio: 'inherit',
|
||||
})
|
||||
|
||||
if (typeof exitCode !== 'number') {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(
|
||||
`Testing with deps: ${depsInfo} finished with missing exit code from execa (received ${exitCode})`,
|
||||
)
|
||||
}
|
||||
|
||||
if (exitCode !== 0) {
|
||||
exit(exitCode)
|
||||
}
|
||||
}
|
||||
exit(0)
|
||||
}
|
||||
|
||||
// execute main function if called from command line
|
||||
if (require.main === module) {
|
||||
main()
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
const execa = require('execa')
|
||||
const pkg = require('./package.json')
|
||||
const fs = require('fs')
|
||||
|
||||
/**
|
||||
* This file installs WebpackDevServer 3 and runs the tests for the dev-server.
|
||||
* We read package.json, update the webpack version, then re-run yarn install.
|
||||
* After it finishes, pass or fail,
|
||||
* we revert the package.json back to the original state.
|
||||
*
|
||||
* The tests for the example projects (inside of examples) run with WebpackDevServer 3.
|
||||
* This ensures we have some coverage for both versions.
|
||||
*/
|
||||
const main = async () => {
|
||||
const originalPkg = JSON.stringify(pkg, null, 2)
|
||||
|
||||
const resetPkg = async () => {
|
||||
fs.writeFileSync('package.json', originalPkg, 'utf8')
|
||||
await execa('yarn', ['install'], { stdio: 'inherit' })
|
||||
}
|
||||
|
||||
const checkExit = async ({ exitCode }) => {
|
||||
if (typeof exitCode !== 'number') {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(`Finished with missing exit code from execa (received ${exitCode})`)
|
||||
}
|
||||
|
||||
await resetPkg()
|
||||
process.exit(exitCode)
|
||||
}
|
||||
|
||||
pkg.devDependencies['webpack-dev-server'] = '3.11.0'
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('[@cypress/webpack-dev-server]: updating package.json...')
|
||||
fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2))
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('[@cypress/webpack-dev-server]: install dependencies...')
|
||||
await execa('yarn', ['install'], { stdio: 'inherit' })
|
||||
|
||||
const { exitCode } = await execa('yarn', ['test-all'], { stdio: 'inherit' })
|
||||
|
||||
await checkExit({ exitCode })
|
||||
}
|
||||
|
||||
// execute main function if called from command line
|
||||
if (require.main === module) {
|
||||
main()
|
||||
}
|
||||
@@ -118,7 +118,10 @@ describe('#startDevServer', () => {
|
||||
|
||||
return new Promise((res) => {
|
||||
devServerEvents.on('dev-server:compile:error', (err: string) => {
|
||||
expect(err).to.contain('./test/fixtures/compilation-fails.spec.js 1:5')
|
||||
if (webpackDevServerFacts.isV3()) {
|
||||
expect(err).to.contain('./test/fixtures/compilation-fails.spec.js 1:5')
|
||||
}
|
||||
|
||||
expect(err).to.contain('Module parse failed: Unexpected token (1:5)')
|
||||
expect(err).to.contain('You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders')
|
||||
expect(err).to.contain('> this is an invalid spec file')
|
||||
@@ -128,7 +131,7 @@ describe('#startDevServer', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('touches browser.js when a spec file is added', async function () {
|
||||
it('touches browser.js when a spec file is added and recompile', async function () {
|
||||
const devServerEvents = new EventEmitter()
|
||||
const { close } = await startDevServer({
|
||||
webpackConfig,
|
||||
@@ -140,19 +143,27 @@ describe('#startDevServer', () => {
|
||||
})
|
||||
|
||||
const newSpec: Cypress.Cypress['spec'] = {
|
||||
name: './some-newly-created-spec.js',
|
||||
relative: './some-newly-created-spec.js',
|
||||
absolute: '/some-newly-created-spec.js',
|
||||
name: `${root}/test/fixtures/bar.spec.js`,
|
||||
relative: `${root}/test/fixtures/bar.spec.js`,
|
||||
absolute: `${root}/test/fixtures/bar.spec.js`,
|
||||
}
|
||||
|
||||
const oldmtime = fs.statSync('./dist/browser.js').mtimeMs
|
||||
|
||||
return new Promise((res) => {
|
||||
devServerEvents.emit('dev-server:specs:changed', [newSpec])
|
||||
const updatedmtime = fs.statSync('./dist/browser.js').mtimeMs
|
||||
let firstCompile = true
|
||||
|
||||
expect(oldmtime).to.not.equal(updatedmtime)
|
||||
close(() => res())
|
||||
return new Promise((res) => {
|
||||
devServerEvents.on('dev-server:compile:success', () => {
|
||||
if (firstCompile) {
|
||||
firstCompile = false
|
||||
devServerEvents.emit('dev-server:specs:changed', [newSpec])
|
||||
const updatedmtime = fs.statSync('./dist/browser.js').mtimeMs
|
||||
|
||||
expect(oldmtime).to.not.equal(updatedmtime)
|
||||
} else {
|
||||
close(() => res())
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
const bar = () => {}
|
||||
@@ -1,3 +1,10 @@
|
||||
# [@cypress/webpack-preprocessor-v5.11.1](https://github.com/cypress-io/cypress/compare/@cypress/webpack-preprocessor-v5.11.0...@cypress/webpack-preprocessor-v5.11.1) (2022-02-08)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* detect newly added specs in dev-server compilation ([#17950](https://github.com/cypress-io/cypress/issues/17950)) ([f9ce67c](https://github.com/cypress-io/cypress/commit/f9ce67cfb6fed74a3549e7aff7ce0a5b217d9a13))
|
||||
|
||||
# [@cypress/webpack-preprocessor-v5.11.0](https://github.com/cypress-io/cypress/compare/@cypress/webpack-preprocessor-v5.10.0...@cypress/webpack-preprocessor-v5.11.0) (2021-12-16)
|
||||
|
||||
|
||||
|
||||
@@ -44,9 +44,9 @@ module.exports = (on) => {
|
||||
|
||||
## Examples
|
||||
|
||||
- [React app](examples/react-app) shows how to point Cypress at Webpack configuration from `react-scripts` dependency
|
||||
- [use-babelrc](examples/use-babelrc) shows how to use your project's `.babelrc` with Webpack
|
||||
- [use-ts-loader](examples/use-ts-loader) shows how to transpile TypeScript specs following [Webpack TypeScript guide](https://webpack.js.org/guides/typescript/)
|
||||
- [React app](https://github.com/cypress-io/cypress/tree/develop/npm/webpack-preprocessor/examples/react-app) shows how to point Cypress at Webpack configuration from `react-scripts` dependency
|
||||
- [use-babelrc](https://github.com/cypress-io/cypress/tree/develop/npm/webpack-preprocessor/examples/use-babelrc) shows how to use your project's `.babelrc` with Webpack
|
||||
- [use-ts-loader](https://github.com/cypress-io/cypress/tree/develop/npm/webpack-preprocessor/examples/use-ts-loader) shows how to transpile TypeScript specs following [Webpack TypeScript guide](https://webpack.js.org/guides/typescript/)
|
||||
|
||||
## Options
|
||||
|
||||
|
||||
@@ -14,9 +14,11 @@ const fs = require('fs')
|
||||
const main = async () => {
|
||||
const originalPkg = JSON.stringify(pkg, null, 2)
|
||||
|
||||
const install = () => execa('yarn', ['install', '--ignore-scripts'], { stdio: 'inherit' })
|
||||
|
||||
const resetPkg = async () => {
|
||||
fs.writeFileSync('package.json', originalPkg, 'utf8')
|
||||
await execa('yarn', ['install'], { stdio: 'inherit' })
|
||||
await install()
|
||||
}
|
||||
|
||||
const checkExit = async ({ exitCode, step }) => {
|
||||
@@ -40,7 +42,7 @@ const main = async () => {
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('[@cypress/webpack-preprocessor]: install dependencies...')
|
||||
await execa('yarn', ['install'], { stdio: 'inherit' })
|
||||
await install()
|
||||
|
||||
const unit = await execa('yarn', ['test-unit'], { stdio: 'inherit' })
|
||||
|
||||
|
||||
+5
-4
@@ -17,15 +17,17 @@
|
||||
"bump": "node ./scripts/binary.js bump",
|
||||
"check-node-version": "node scripts/check-node-version.js",
|
||||
"check-terminal": "node scripts/check-terminal.js",
|
||||
"clean": "lerna run clean --parallel --no-bail",
|
||||
"clean": "lerna run clean --parallel --no-bail || echo 'ok, errors while cleaning'",
|
||||
"clean-deps": "find . -depth -name node_modules -type d -exec rm -rf {} \\;",
|
||||
"clean-untracked-files": "git clean -d -f",
|
||||
"precypress:open": "yarn ensure-deps",
|
||||
"cypress:open": "cypress open --dev --global",
|
||||
"cypress:open:ct": "cypress open-ct --dev --global",
|
||||
"precypress:open:debug": "yarn ensure-deps",
|
||||
"cypress:open:debug": "node ./scripts/debug.js cypress:open",
|
||||
"precypress:run": "yarn ensure-deps",
|
||||
"cypress:run": "cypress run --dev",
|
||||
"cypress:run:ct": "cypress run-ct --dev",
|
||||
"precypress:run:debug": "yarn ensure-deps",
|
||||
"cypress:run:debug": "node ./scripts/debug.js cypress:run",
|
||||
"cypress:verify": "cypress verify --dev",
|
||||
@@ -46,7 +48,7 @@
|
||||
"stop-only": "npx stop-only --skip .cy,.publish,.projects,node_modules,dist,dist-test,fixtures,lib,bower_components,src,__snapshots__ --exclude e2e.ts,cypress-tests.ts,*only_spec.js",
|
||||
"stop-only-all": "yarn stop-only --folder packages",
|
||||
"pretest": "yarn ensure-deps",
|
||||
"test": "yarn lerna exec yarn test --scope cypress --scope \"'@packages/{config,electron,extension,https-proxy,launcher,net-stubbing,network,proxy,rewriter,runner,runner-shared,socket}'\"",
|
||||
"test": "yarn lerna exec yarn test --scope cypress --scope \"'@packages/{config,errors,electron,extension,https-proxy,launcher,net-stubbing,network,proxy,rewriter,runner,runner-shared,socket}'\"",
|
||||
"test-debug": "lerna exec yarn test-debug --ignore \"'@packages/{desktop-gui,driver,root,static,web-config}'\"",
|
||||
"pretest-e2e": "yarn ensure-deps",
|
||||
"test-integration": "lerna exec yarn test-integration --ignore \"'@packages/{desktop-gui,driver,root,static,web-config}'\"",
|
||||
@@ -103,7 +105,6 @@
|
||||
"@types/sinon-chai": "3.2.3",
|
||||
"@typescript-eslint/eslint-plugin": "4.18.0",
|
||||
"@typescript-eslint/parser": "4.18.0",
|
||||
"ansi-styles": "3.2.1",
|
||||
"arg": "4.1.2",
|
||||
"ascii-table": "0.0.9",
|
||||
"aws-sdk": "2.814.0",
|
||||
@@ -181,7 +182,7 @@
|
||||
"snap-shot-it": "7.9.3",
|
||||
"start-server-and-test": "1.10.8",
|
||||
"stop-only": "3.0.1",
|
||||
"strip-ansi": "4.0.0",
|
||||
"strip-ansi": "6.0.0",
|
||||
"term-to-html": "1.2.0",
|
||||
"terminal-banner": "1.1.0",
|
||||
"through": "2.3.8",
|
||||
|
||||
@@ -6,73 +6,113 @@ exports['empty list of browsers'] = `
|
||||
Expected at least one browser
|
||||
`
|
||||
|
||||
exports['browsers list with a string'] = `
|
||||
Found an error while validating the \`browsers\` list. Expected \`name\` to be a non-empty string. Instead the value was: \`"foo"\`
|
||||
`
|
||||
exports['browsers list with a string'] = {
|
||||
"key": "name",
|
||||
"value": "foo",
|
||||
"type": "a non-empty string",
|
||||
"list": "browsers"
|
||||
}
|
||||
|
||||
exports['not one of the strings error message'] = `
|
||||
Expected \`test\` to be one of these values: "foo", "bar". Instead the value was: \`"nope"\`
|
||||
`
|
||||
exports['not one of the strings error message'] = {
|
||||
"key": "test",
|
||||
"value": "nope",
|
||||
"type": "one of these values: \"foo\", \"bar\""
|
||||
}
|
||||
|
||||
exports['number instead of string'] = `
|
||||
Expected \`test\` to be one of these values: "foo", "bar". Instead the value was: \`42\`
|
||||
`
|
||||
exports['number instead of string'] = {
|
||||
"key": "test",
|
||||
"value": 42,
|
||||
"type": "one of these values: \"foo\", \"bar\""
|
||||
}
|
||||
|
||||
exports['null instead of string'] = `
|
||||
Expected \`test\` to be one of these values: "foo", "bar". Instead the value was: \`null\`
|
||||
`
|
||||
exports['null instead of string'] = {
|
||||
"key": "test",
|
||||
"value": null,
|
||||
"type": "one of these values: \"foo\", \"bar\""
|
||||
}
|
||||
|
||||
exports['not one of the numbers error message'] = `
|
||||
Expected \`test\` to be one of these values: 1, 2, 3. Instead the value was: \`4\`
|
||||
`
|
||||
exports['not one of the numbers error message'] = {
|
||||
"key": "test",
|
||||
"value": 4,
|
||||
"type": "one of these values: 1, 2, 3"
|
||||
}
|
||||
|
||||
exports['string instead of a number'] = `
|
||||
Expected \`test\` to be one of these values: 1, 2, 3. Instead the value was: \`"foo"\`
|
||||
`
|
||||
exports['string instead of a number'] = {
|
||||
"key": "test",
|
||||
"value": "foo",
|
||||
"type": "one of these values: 1, 2, 3"
|
||||
}
|
||||
|
||||
exports['null instead of a number'] = `
|
||||
Expected \`test\` to be one of these values: 1, 2, 3. Instead the value was: \`null\`
|
||||
`
|
||||
exports['null instead of a number'] = {
|
||||
"key": "test",
|
||||
"value": null,
|
||||
"type": "one of these values: 1, 2, 3"
|
||||
}
|
||||
|
||||
exports['not string or array'] = `
|
||||
Expected \`mockConfigKey\` to be a string or an array of strings. Instead the value was: \`null\`
|
||||
`
|
||||
exports['not string or array'] = {
|
||||
"key": "mockConfigKey",
|
||||
"value": null,
|
||||
"type": "a string or an array of strings"
|
||||
}
|
||||
|
||||
exports['array of non-strings'] = `
|
||||
Expected \`mockConfigKey\` to be a string or an array of strings. Instead the value was: \`[1,2,3]\`
|
||||
`
|
||||
exports['array of non-strings'] = {
|
||||
"key": "mockConfigKey",
|
||||
"value": [
|
||||
1,
|
||||
2,
|
||||
3
|
||||
],
|
||||
"type": "a string or an array of strings"
|
||||
}
|
||||
|
||||
exports['invalid retry value'] = `
|
||||
Expected \`mockConfigKey\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. Instead the value was: \`"1"\`
|
||||
`
|
||||
exports['invalid retry value'] = {
|
||||
"key": "mockConfigKey",
|
||||
"value": "1",
|
||||
"type": "a positive number or null or an object with keys \"openMode\" and \"runMode\" with values of numbers or nulls"
|
||||
}
|
||||
|
||||
exports['invalid retry object'] = `
|
||||
Expected \`mockConfigKey\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. Instead the value was: \`{"fakeMode":1}\`
|
||||
`
|
||||
exports['invalid retry object'] = {
|
||||
"key": "mockConfigKey",
|
||||
"value": {
|
||||
"fakeMode": 1
|
||||
},
|
||||
"type": "a positive number or null or an object with keys \"openMode\" and \"runMode\" with values of numbers or nulls"
|
||||
}
|
||||
|
||||
exports['missing https protocol'] = `
|
||||
Expected \`clientCertificates[0].url\` to be an https protocol. Instead the value was: \`"http://url.com"\`
|
||||
`
|
||||
exports['missing https protocol'] = {
|
||||
"key": "clientCertificates[0].url",
|
||||
"value": "http://url.com",
|
||||
"type": "an https protocol"
|
||||
}
|
||||
|
||||
exports['invalid url'] = `
|
||||
Expected \`clientCertificates[0].url\` to be a valid URL. Instead the value was: \`"not *"\`
|
||||
`
|
||||
exports['invalid url'] = {
|
||||
"key": "clientCertificates[0].url",
|
||||
"value": "not *",
|
||||
"type": "a valid URL"
|
||||
}
|
||||
|
||||
exports['not qualified url'] = `
|
||||
Expected \`mockConfigKey\` to be a fully qualified URL (starting with \`http://\` or \`https://\`). Instead the value was: \`"url.com"\`
|
||||
`
|
||||
exports['not qualified url'] = {
|
||||
"key": "mockConfigKey",
|
||||
"value": "url.com",
|
||||
"type": "a fully qualified URL (starting with `http://` or `https://`)"
|
||||
}
|
||||
|
||||
exports['empty string'] = `
|
||||
Expected \`mockConfigKey\` to be a fully qualified URL (starting with \`http://\` or \`https://\`). Instead the value was: \`""\`
|
||||
`
|
||||
exports['empty string'] = {
|
||||
"key": "mockConfigKey",
|
||||
"value": "",
|
||||
"type": "a fully qualified URL (starting with `http://` or `https://`)"
|
||||
}
|
||||
|
||||
exports['config/lib/validation .isValidClientCertificatesSet returns error message for certs not passed as an array array 1'] = `
|
||||
Expected \`mockConfigKey\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. Instead the value was: \`"1"\`
|
||||
`
|
||||
exports['config/lib/validation .isValidClientCertificatesSet returns error message for certs not passed as an array array 1'] = {
|
||||
"key": "mockConfigKey",
|
||||
"value": "1",
|
||||
"type": "a positive number or null or an object with keys \"openMode\" and \"runMode\" with values of numbers or nulls"
|
||||
}
|
||||
|
||||
exports['config/lib/validation .isValidClientCertificatesSet returns error message for certs object without url 1'] = `
|
||||
Expected \`clientCertificates[0].url\` to be a URL matcher. Instead the value was: \`undefined\`
|
||||
`
|
||||
exports['config/lib/validation .isValidClientCertificatesSet returns error message for certs object without url 1'] = {
|
||||
"key": "clientCertificates[0].url",
|
||||
"type": "a URL matcher"
|
||||
}
|
||||
|
||||
exports['config/lib/validation .isValidBrowser passes valid browsers and forms error messages for invalid ones isValidBrowser 1'] = {
|
||||
"name": "isValidBrowser",
|
||||
@@ -115,7 +155,14 @@ exports['config/lib/validation .isValidBrowser passes valid browsers and forms e
|
||||
"name": "No display name",
|
||||
"family": "chromium"
|
||||
},
|
||||
"expect": "Expected `displayName` to be a non-empty string. Instead the value was: `{\"name\":\"No display name\",\"family\":\"chromium\"}`"
|
||||
"expect": {
|
||||
"key": "displayName",
|
||||
"value": {
|
||||
"name": "No display name",
|
||||
"family": "chromium"
|
||||
},
|
||||
"type": "a non-empty string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"given": {
|
||||
@@ -123,35 +170,57 @@ exports['config/lib/validation .isValidBrowser passes valid browsers and forms e
|
||||
"displayName": "Bad family browser",
|
||||
"family": "unknown family"
|
||||
},
|
||||
"expect": "Expected `family` to be either chromium or firefox. Instead the value was: `{\"name\":\"bad family\",\"displayName\":\"Bad family browser\",\"family\":\"unknown family\"}`"
|
||||
"expect": {
|
||||
"key": "family",
|
||||
"value": {
|
||||
"name": "bad family",
|
||||
"displayName": "Bad family browser",
|
||||
"family": "unknown family"
|
||||
},
|
||||
"type": "either chromium or firefox"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
exports['config/lib/validation .isPlainObject returns error message when value is a not an object 1'] = `
|
||||
Expected \`mockConfigKey\` to be a plain object. Instead the value was: \`1\`
|
||||
`
|
||||
exports['config/lib/validation .isPlainObject returns error message when value is a not an object 1'] = {
|
||||
"key": "mockConfigKey",
|
||||
"value": 1,
|
||||
"type": "a plain object"
|
||||
}
|
||||
|
||||
exports['config/lib/validation .isNumber returns error message when value is a not a number 1'] = `
|
||||
Expected \`mockConfigKey\` to be a number. Instead the value was: \`"string"\`
|
||||
`
|
||||
exports['config/lib/validation .isNumber returns error message when value is a not a number 1'] = {
|
||||
"key": "mockConfigKey",
|
||||
"value": "string",
|
||||
"type": "a number"
|
||||
}
|
||||
|
||||
exports['config/lib/validation .isNumberOrFalse returns error message when value is a not number or false 1'] = `
|
||||
Expected \`mockConfigKey\` to be a number or false. Instead the value was: \`null\`
|
||||
`
|
||||
exports['config/lib/validation .isNumberOrFalse returns error message when value is a not number or false 1'] = {
|
||||
"key": "mockConfigKey",
|
||||
"value": null,
|
||||
"type": "a number or false"
|
||||
}
|
||||
|
||||
exports['config/lib/validation .isBoolean returns error message when value is a not a string 1'] = `
|
||||
Expected \`mockConfigKey\` to be a string. Instead the value was: \`1\`
|
||||
`
|
||||
exports['config/lib/validation .isBoolean returns error message when value is a not a string 1'] = {
|
||||
"key": "mockConfigKey",
|
||||
"value": 1,
|
||||
"type": "a string"
|
||||
}
|
||||
|
||||
exports['config/lib/validation .isString returns error message when value is a not a string 1'] = `
|
||||
Expected \`mockConfigKey\` to be a string. Instead the value was: \`1\`
|
||||
`
|
||||
exports['config/lib/validation .isString returns error message when value is a not a string 1'] = {
|
||||
"key": "mockConfigKey",
|
||||
"value": 1,
|
||||
"type": "a string"
|
||||
}
|
||||
|
||||
exports['config/lib/validation .isArray returns error message when value is a non-array 1'] = `
|
||||
Expected \`mockConfigKey\` to be an array. Instead the value was: \`1\`
|
||||
`
|
||||
exports['config/lib/validation .isArray returns error message when value is a non-array 1'] = {
|
||||
"key": "mockConfigKey",
|
||||
"value": 1,
|
||||
"type": "an array"
|
||||
}
|
||||
|
||||
exports['config/lib/validation .isStringOrFalse returns error message when value is neither string nor false 1'] = `
|
||||
Expected \`mockConfigKey\` to be a string or false. Instead the value was: \`null\`
|
||||
`
|
||||
exports['config/lib/validation .isStringOrFalse returns error message when value is neither string nor false 1'] = {
|
||||
"key": "mockConfigKey",
|
||||
"value": null,
|
||||
"type": "a string or false"
|
||||
}
|
||||
|
||||
@@ -11,17 +11,12 @@ const path = require('path')
|
||||
const str = JSON.stringify
|
||||
const { isArray, isString, isFinite: isNumber } = _
|
||||
|
||||
/**
|
||||
* Forms good Markdown-like string message.
|
||||
* @param {string} key - The key that caused the error
|
||||
* @param {string} type - The expected type name
|
||||
* @param {any} value - The actual value
|
||||
* @returns {string} Formatted error message
|
||||
*/
|
||||
const errMsg = (key, value, type) => {
|
||||
return `Expected \`${key}\` to be ${type}. Instead the value was: \`${str(
|
||||
return {
|
||||
key,
|
||||
value,
|
||||
)}\``
|
||||
type,
|
||||
}
|
||||
}
|
||||
|
||||
const isFullyQualifiedUrl = (value) => {
|
||||
@@ -91,10 +86,12 @@ const isValidBrowserList = (key, browsers) => {
|
||||
}
|
||||
|
||||
for (let k = 0; k < browsers.length; k += 1) {
|
||||
const err = isValidBrowser(browsers[k])
|
||||
const validationResult = isValidBrowser(browsers[k])
|
||||
|
||||
if (err !== true) {
|
||||
return `Found an error while validating the \`browsers\` list. ${err}`
|
||||
if (validationResult !== true) {
|
||||
validationResult.list = 'browsers'
|
||||
|
||||
return validationResult
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -104,7 +104,8 @@ describe('config/lib/index', () => {
|
||||
'baseUrl': ' ',
|
||||
}, errorFn)
|
||||
|
||||
expect(errorFn).to.have.been.calledWithMatch(/Expected `baseUrl`/)
|
||||
expect(errorFn).to.have.been.calledWithMatch({ key: 'baseUrl' })
|
||||
expect(errorFn).to.have.been.calledWithMatch({ type: 'a fully qualified URL (starting with `http://` or `https://`)' })
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -124,7 +124,13 @@ describe('Error Message', function () {
|
||||
.should('contain', 'this is markdown')
|
||||
})
|
||||
|
||||
it('shows error details if provided', function () {
|
||||
it('shows error details collapsed if cypress originalError provided', function () {
|
||||
this.detailsErr.originalError = {
|
||||
...this.detailsErr,
|
||||
stack: this.detailsErr.details,
|
||||
isCypressErr: true,
|
||||
}
|
||||
|
||||
cy.stub(this.ipc, 'onProjectError').yields(null, this.detailsErr)
|
||||
this.start()
|
||||
|
||||
@@ -134,6 +140,20 @@ describe('Error Message', function () {
|
||||
cy.get('details.details-body > summary').should('contain', 'ReferenceError')
|
||||
})
|
||||
|
||||
it('shows error details open if non cypress originalError provided', function () {
|
||||
this.detailsErr.originalError = {
|
||||
...this.detailsErr,
|
||||
stack: this.detailsErr.details,
|
||||
}
|
||||
|
||||
cy.stub(this.ipc, 'onProjectError').yields(null, this.detailsErr)
|
||||
this.start()
|
||||
|
||||
cy.get('.error').contains('ReferenceError: alsdkjf is not defined')
|
||||
cy.get('details.details-body').should('have.attr', 'open')
|
||||
cy.get('details.details-body > summary').should('contain', 'ReferenceError')
|
||||
})
|
||||
|
||||
it('doesn\'t show error details if not provided', function () {
|
||||
cy.stub(this.ipc, 'onProjectError').yields(null, this.err)
|
||||
this.start()
|
||||
@@ -173,7 +193,7 @@ describe('Error Message', function () {
|
||||
this.detailsErr = {
|
||||
name: 'Error',
|
||||
message: messageText,
|
||||
stack: '[object Object]↵',
|
||||
stack: 'ReferenceError: alsdkjf is not defined',
|
||||
details: 'ReferenceError: alsdkjf is not defined',
|
||||
}
|
||||
|
||||
@@ -219,7 +239,12 @@ describe('Error Message', function () {
|
||||
})
|
||||
|
||||
it('does not overlay the nav/footer when long details are expanded (issue #4959)', function () {
|
||||
this.detailsErr.details = `${this.detailsErr.details}${this.detailsErr.details}` // make details longer
|
||||
this.detailsErr.originalError = {
|
||||
...this.detailsErr,
|
||||
stack: `${this.detailsErr.details}${this.detailsErr.details}`, // make details longer
|
||||
isCypressErr: true,
|
||||
}
|
||||
|
||||
this.ipc.openProject.rejects(this.detailsErr)
|
||||
this.start()
|
||||
|
||||
@@ -229,7 +254,12 @@ describe('Error Message', function () {
|
||||
})
|
||||
|
||||
it('it scrolls the error details when details are expanded (issue #4959)', function () {
|
||||
this.detailsErr.details = `${this.detailsErr.details}${this.detailsErr.details}` // make details longer
|
||||
this.detailsErr.originalError = {
|
||||
...this.detailsErr,
|
||||
stack: `${this.detailsErr.details}${this.detailsErr.details}`, // make details longer
|
||||
isCypressErr: true,
|
||||
}
|
||||
|
||||
this.ipc.openProject.rejects(this.detailsErr)
|
||||
this.start()
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import Markdown from 'markdown-it'
|
||||
|
||||
const _copyErrorDetails = (err) => {
|
||||
let details = [
|
||||
`**Message:** ${err.message}`,
|
||||
`**Message:** ${err.messageMarkdown || err.message}`,
|
||||
]
|
||||
|
||||
if (err.details) {
|
||||
@@ -33,14 +33,14 @@ const md = new Markdown({
|
||||
})
|
||||
|
||||
const ErrorDetails = observer(({ err }) => {
|
||||
let details = _.clone(err.details).split('\n')
|
||||
let details = _.clone(err.stack).split('\n')
|
||||
const detailsTitle = details.shift()
|
||||
const detailsBody = details.join('\n')
|
||||
|
||||
if (detailsBody) {
|
||||
return (
|
||||
<pre>
|
||||
<details className='details-body'>
|
||||
<details className='details-body' open={!err.isCypressErr}>
|
||||
<summary>{detailsTitle}</summary>
|
||||
{detailsBody}
|
||||
</details>
|
||||
@@ -85,10 +85,10 @@ class ErrorMessage extends Component {
|
||||
</p>
|
||||
<span className='alert-content'>
|
||||
<div ref={(node) => this.errorMessageNode = node} dangerouslySetInnerHTML={{
|
||||
__html: md.render(err.message),
|
||||
__html: md.render(err.messageMarkdown || err.message),
|
||||
}}></div>
|
||||
{err.details && (
|
||||
<ErrorDetails err={err} />
|
||||
{err.originalError && (
|
||||
<ErrorDetails err={err.originalError} />
|
||||
)}
|
||||
{err.portInUse && (
|
||||
<div>
|
||||
@@ -96,7 +96,7 @@ class ErrorMessage extends Component {
|
||||
<p>To fix, stop the other running process or change the port in {configFileFormatted(this.props.project.configFile)}</p>
|
||||
</div>
|
||||
)}
|
||||
{err.stack2 && (
|
||||
{!err.originalError && err.stack2 && (
|
||||
<details className='stacktrace'>
|
||||
<summary>Stack trace</summary>
|
||||
<pre>{err.stack2}</pre>
|
||||
|
||||
@@ -6,3 +6,7 @@
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
details.stacktrace summary {
|
||||
display: list-item;
|
||||
}
|
||||
|
||||
+10
-10
@@ -1,19 +1,19 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>type('{enter}') </title>
|
||||
<title>Click Event by cy.type()</title>
|
||||
<meta charset="UTF-8" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<button id="reset">clear log</button>
|
||||
<button id="target-button-tag">click me then press enter</button>
|
||||
<input id="target-input-button" type="button" value="click me then press enter" />
|
||||
<input id="target-input-image" type="image" value="click me then press enter" />
|
||||
<input id="target-input-reset" type="reset" value="click me then press enter" />
|
||||
<input id="target-input-submit" type="submit" value="click me then press enter" />
|
||||
<input id="target-input-checkbox" type="checkbox" value="click me then press enter" />
|
||||
<input id="target-input-radio" type="radio" value="click me then press enter" />
|
||||
<button id="target-button-tag">button tag</button>
|
||||
<input id="target-input-button" type="button" value="input button" />
|
||||
<input id="target-input-image" type="image" value="input image" />
|
||||
<input id="target-input-reset" type="reset" value="input reset" />
|
||||
<input id="target-input-submit" type="submit" value="input submit" />
|
||||
<input id="target-input-checkbox" type="checkbox" value="input checkbox" />
|
||||
<input id="target-input-radio" type="radio" value="input radio" />
|
||||
|
||||
<div id="log"></div>
|
||||
|
||||
@@ -66,10 +66,10 @@
|
||||
target.addEventListener("click", () => {
|
||||
updateLog("click");
|
||||
});
|
||||
target.addEventListener("keyup", () => {
|
||||
target.addEventListener("keyup", (event) => {
|
||||
updateLog("keyup");
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
@@ -0,0 +1,32 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset='utf-8'>
|
||||
<title>Select event counter</title>
|
||||
</head>
|
||||
<label>Choose an ice cream flavor:
|
||||
<select class='ice-cream' name='ice-cream'>
|
||||
<option value=''>Select One …</option>
|
||||
<option value='chocolate' selected>Chocolate</option>
|
||||
<option value='sardine'>Sardine</option>
|
||||
<option value='vanilla'>Vanilla</option>
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<div id='change-result'></div>
|
||||
<div id='input-result'></div>
|
||||
|
||||
<script>
|
||||
const selectElement = document.querySelector('.ice-cream');
|
||||
let numOfTimesOnChangeFired = 0;
|
||||
selectElement.addEventListener('change', (event) => {
|
||||
const result = document.querySelector('#change-result');
|
||||
result.textContent = `Number of times onChange event fired: ${++numOfTimesOnChangeFired}`;
|
||||
});
|
||||
|
||||
let numOfTimesInputFired = 0;
|
||||
selectElement.addEventListener('input', (event) => {
|
||||
const result = document.querySelector('#input-result');
|
||||
result.textContent = `Number of times input event fired: ${++numOfTimesInputFired}`;
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
@@ -325,6 +325,25 @@ describe('src/cy/commands/actions/select', () => {
|
||||
expect(fired).to.deep.eq(events)
|
||||
})
|
||||
})
|
||||
|
||||
// https://github.com/cypress-io/cypress/issues/19494
|
||||
it('does not fire `change`, `input` events when selecting the same option again', () => {
|
||||
cy.visit('fixtures/select-event-counter.html')
|
||||
|
||||
// Nothing happens when selecting the option with `selected` attribute
|
||||
cy.get('.ice-cream').select('Chocolate')
|
||||
cy.get('#change-result').should('not.have.text', 'Number of times onChange event fired: 1')
|
||||
cy.get('#input-result').should('not.have.text', 'Number of times input event fired: 1')
|
||||
|
||||
cy.get('.ice-cream').select('Sardine')
|
||||
cy.get('#change-result').should('have.text', 'Number of times onChange event fired: 1')
|
||||
cy.get('#input-result').should('have.text', 'Number of times input event fired: 1')
|
||||
|
||||
// Select the option that is already selected - `change`, `input` events should not fire.
|
||||
cy.get('.ice-cream').select('Sardine')
|
||||
cy.get('#change-result').should('have.text', 'Number of times onChange event fired: 1')
|
||||
cy.get('#input-result').should('have.text', 'Number of times input event fired: 1')
|
||||
})
|
||||
})
|
||||
|
||||
describe('errors', {
|
||||
@@ -365,7 +384,7 @@ describe('src/cy/commands/actions/select', () => {
|
||||
done()
|
||||
})
|
||||
|
||||
cy.get('#select-maps').select('de_dust2').select('de_aztec')
|
||||
cy.get('#select-maps').select('de_aztec').select('de_dust2')
|
||||
})
|
||||
|
||||
it('throws when more than 1 element in the collection', (done) => {
|
||||
@@ -647,7 +666,7 @@ describe('src/cy/commands/actions/select', () => {
|
||||
done()
|
||||
})
|
||||
|
||||
cy.get('#select-maps').select('de_dust2').then(($select) => { })
|
||||
cy.get('#select-maps').select('de_aztec').then(($select) => { })
|
||||
})
|
||||
|
||||
it('snapshots after clicking', () => {
|
||||
|
||||
@@ -560,7 +560,7 @@ describe('src/cy/commands/actions/type - #type', () => {
|
||||
// https://github.com/cypress-io/cypress/issues/19541
|
||||
describe(`type('{enter}') and click event on button-like elements`, () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('fixtures/type-enter.html')
|
||||
cy.visit('fixtures/click-event-by-type.html')
|
||||
})
|
||||
|
||||
describe('triggers', () => {
|
||||
@@ -574,8 +574,7 @@ describe('src/cy/commands/actions/type - #type', () => {
|
||||
|
||||
targets.forEach((targetId) => {
|
||||
it(`${targetId}`, () => {
|
||||
cy.get(`#target-${targetId}`).focus()
|
||||
cy.get(`#target-${targetId}`).type('{enter}')
|
||||
cy.get(`#target-${targetId}`).focus().type('{enter}')
|
||||
|
||||
cy.get('li').eq(0).should('have.text', 'keydown')
|
||||
cy.get('li').eq(1).should('have.text', 'keypress')
|
||||
@@ -593,8 +592,7 @@ describe('src/cy/commands/actions/type - #type', () => {
|
||||
|
||||
targets.forEach((targetId) => {
|
||||
it(`${targetId}`, () => {
|
||||
cy.get(`#target-${targetId}`).focus()
|
||||
cy.get(`#target-${targetId}`).type('{enter}')
|
||||
cy.get(`#target-${targetId}`).focus().type('{enter}')
|
||||
|
||||
cy.get('li').eq(0).should('have.text', 'keydown')
|
||||
cy.get('li').eq(1).should('have.text', 'keypress')
|
||||
@@ -604,6 +602,154 @@ describe('src/cy/commands/actions/type - #type', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe(`type(' ') fires click event on button-like elements`, () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('fixtures/click-event-by-type.html')
|
||||
})
|
||||
|
||||
const targets = [
|
||||
'#target-button-tag',
|
||||
'#target-input-button',
|
||||
'#target-input-image',
|
||||
'#target-input-reset',
|
||||
'#target-input-submit',
|
||||
]
|
||||
|
||||
describe(`triggers with single space`, () => {
|
||||
targets.forEach((target) => {
|
||||
it(target, () => {
|
||||
const events = []
|
||||
|
||||
$(target).on('keydown keypress keyup click', (evt) => {
|
||||
events.push(evt.type)
|
||||
})
|
||||
|
||||
cy.get(target).focus().type(' ').then(() => {
|
||||
expect(events).to.deep.eq([
|
||||
'keydown',
|
||||
'keypress',
|
||||
'keyup',
|
||||
'click',
|
||||
])
|
||||
})
|
||||
|
||||
cy.get('li').eq(0).should('have.text', 'keydown')
|
||||
cy.get('li').eq(1).should('have.text', 'keypress')
|
||||
cy.get('li').eq(2).should('have.text', 'keyup')
|
||||
cy.get('li').eq(3).should('have.text', 'click')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe(`does not trigger if keyup prevented`, () => {
|
||||
targets.forEach((target) => {
|
||||
it(`${target} does not fire click event`, () => {
|
||||
const events = []
|
||||
|
||||
$(target)
|
||||
.on('keydown keypress keyup click', (evt) => {
|
||||
events.push(evt.type)
|
||||
})
|
||||
.on('keyup', (evt) => {
|
||||
evt.preventDefault()
|
||||
})
|
||||
|
||||
cy.get(target).focus().type(' ').then(() => {
|
||||
expect(events).to.deep.eq([
|
||||
'keydown',
|
||||
'keypress',
|
||||
'keyup',
|
||||
])
|
||||
})
|
||||
|
||||
cy.get('li').should('have.length', 3)
|
||||
cy.get('li').eq(0).should('have.text', 'keydown')
|
||||
cy.get('li').eq(1).should('have.text', 'keypress')
|
||||
cy.get('li').eq(2).should('have.text', 'keyup')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('triggers after other characters', () => {
|
||||
targets.forEach((target) => {
|
||||
it(target, () => {
|
||||
const events = []
|
||||
|
||||
$(target).on('keydown keypress keyup click', (evt) => {
|
||||
events.push(evt.type)
|
||||
})
|
||||
|
||||
cy.get(target).focus().type('asd ').then(() => {
|
||||
expect(events).to.deep.eq([
|
||||
'keydown',
|
||||
'keypress',
|
||||
'keyup',
|
||||
'keydown',
|
||||
'keypress',
|
||||
'keyup',
|
||||
'keydown',
|
||||
'keypress',
|
||||
'keyup',
|
||||
'keydown',
|
||||
'keypress',
|
||||
'keyup',
|
||||
'click',
|
||||
])
|
||||
})
|
||||
|
||||
cy.get('li').eq(12).should('have.text', 'click')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('checkbox', () => {
|
||||
it('checkbox is checked/unchecked', () => {
|
||||
cy.get(`#target-input-checkbox`).focus().type(' ')
|
||||
|
||||
cy.get('li').eq(0).should('have.text', 'keydown')
|
||||
cy.get('li').eq(1).should('have.text', 'keypress')
|
||||
cy.get('li').eq(2).should('have.text', 'keyup')
|
||||
cy.get('li').eq(3).should('have.text', 'click')
|
||||
|
||||
cy.get('#target-input-checkbox').should('be.checked')
|
||||
|
||||
cy.get(`#target-input-checkbox`).type(' ')
|
||||
|
||||
cy.get('li').eq(4).should('have.text', 'keydown')
|
||||
cy.get('li').eq(5).should('have.text', 'keypress')
|
||||
cy.get('li').eq(6).should('have.text', 'keyup')
|
||||
cy.get('li').eq(7).should('have.text', 'click')
|
||||
|
||||
cy.get('#target-input-checkbox').should('not.be.checked')
|
||||
})
|
||||
})
|
||||
|
||||
describe('radio', () => {
|
||||
it('radio fires click event when it is not checked', () => {
|
||||
cy.get(`#target-input-radio`).focus().type(' ')
|
||||
|
||||
cy.get('li').eq(0).should('have.text', 'keydown')
|
||||
cy.get('li').eq(1).should('have.text', 'keypress')
|
||||
cy.get('li').eq(2).should('have.text', 'keyup')
|
||||
cy.get('li').eq(3).should('have.text', 'click')
|
||||
|
||||
cy.get('#target-input-radio').should('be.checked')
|
||||
})
|
||||
|
||||
it('radio does not fire click event when it is checked', () => {
|
||||
// We're clicking here first to make the radio element checked.
|
||||
cy.get(`#target-input-radio`).click().type(' ')
|
||||
|
||||
// item 0 is click event. It's fired because we want to make sure our radio button is checked.
|
||||
cy.get('li').eq(1).should('have.text', 'keydown')
|
||||
cy.get('li').eq(2).should('have.text', 'keypress')
|
||||
cy.get('li').eq(3).should('have.text', 'keyup')
|
||||
|
||||
cy.get('#target-input-radio').should('be.checked')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('tabindex', () => {
|
||||
beforeEach(function () {
|
||||
this.$div = cy.$$('#tabindex')
|
||||
|
||||
@@ -0,0 +1,227 @@
|
||||
const { assertLogLength } = require('../../../support/utils')
|
||||
|
||||
const { _ } = Cypress
|
||||
|
||||
describe('src/cy/commands/querying', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/fixtures/dom.html')
|
||||
})
|
||||
|
||||
context('#focused', () => {
|
||||
it('returns the activeElement', () => {
|
||||
const $button = cy.$$('#button')
|
||||
|
||||
$button.get(0).focus()
|
||||
|
||||
expect(cy.state('document').activeElement).to.eq($button.get(0))
|
||||
|
||||
cy.focused().then(($focused) => {
|
||||
expect($focused.get(0)).to.eq($button.get(0))
|
||||
})
|
||||
})
|
||||
|
||||
it('returns null if no activeElement', () => {
|
||||
const $button = cy.$$('#button')
|
||||
|
||||
$button.get(0).focus()
|
||||
$button.get(0).blur()
|
||||
|
||||
cy.focused().should('not.exist').then(($focused) => {
|
||||
expect($focused).to.be.null
|
||||
})
|
||||
})
|
||||
|
||||
describe('assertion verification', () => {
|
||||
beforeEach(function () {
|
||||
cy.on('log:added', (attrs, log) => {
|
||||
if (log.get('name') === 'assert') {
|
||||
this.lastLog = log
|
||||
}
|
||||
})
|
||||
|
||||
return null
|
||||
})
|
||||
|
||||
it('eventually passes the assertion', () => {
|
||||
cy.on('command:retry', _.after(2, () => {
|
||||
cy.$$(':text:first').addClass('focused').focus()
|
||||
}))
|
||||
|
||||
cy.focused().should('have.class', 'focused').then(function () {
|
||||
const { lastLog } = this
|
||||
|
||||
expect(lastLog.get('name')).to.eq('assert')
|
||||
expect(lastLog.get('state')).to.eq('passed')
|
||||
|
||||
expect(lastLog.get('ended')).to.be.true
|
||||
})
|
||||
})
|
||||
|
||||
// https://github.com/cypress-io/cypress/issues/409
|
||||
it('retries on an elements value', () => {
|
||||
const $input = cy.$$('input:first')
|
||||
|
||||
cy.on('command:retry', _.after(2, () => {
|
||||
$input.val('1234')
|
||||
|
||||
$input.get(0).focus()
|
||||
}))
|
||||
|
||||
cy.focused().should('have.value', '1234').then(function () {
|
||||
const { lastLog } = this
|
||||
|
||||
expect(lastLog.get('name')).to.eq('assert')
|
||||
expect(lastLog.get('state')).to.eq('passed')
|
||||
|
||||
expect(lastLog.get('ended')).to.be.true
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('.log', () => {
|
||||
beforeEach(function () {
|
||||
cy.$$('input:first').get(0).focus()
|
||||
|
||||
cy.on('log:added', (attrs, log) => {
|
||||
if (log.get('name') === 'focused') {
|
||||
this.lastLog = log
|
||||
}
|
||||
})
|
||||
|
||||
return null
|
||||
})
|
||||
|
||||
it('is a parent command', () => {
|
||||
cy.get('body').focused().then(function () {
|
||||
const { lastLog } = this
|
||||
|
||||
expect(lastLog.get('type')).to.eq('parent')
|
||||
})
|
||||
})
|
||||
|
||||
it('ends immediately', () => {
|
||||
cy.focused().then(function () {
|
||||
const { lastLog } = this
|
||||
|
||||
expect(lastLog.get('ended')).to.be.true
|
||||
|
||||
expect(lastLog.get('state')).to.eq('passed')
|
||||
})
|
||||
})
|
||||
|
||||
it('snapshots immediately', () => {
|
||||
cy.focused().then(function () {
|
||||
const { lastLog } = this
|
||||
|
||||
expect(lastLog.get('snapshots').length).to.eq(1)
|
||||
|
||||
expect(lastLog.get('snapshots')[0]).to.be.an('object')
|
||||
})
|
||||
})
|
||||
|
||||
it('passes in $el', () => {
|
||||
cy.get('input:first').focused().then(function ($input) {
|
||||
const { lastLog } = this
|
||||
|
||||
expect(lastLog.get('$el')).to.eq($input)
|
||||
})
|
||||
})
|
||||
|
||||
it('#consoleProps', () => {
|
||||
cy.get('input:first').focused().then(function ($input) {
|
||||
expect(this.lastLog.invoke('consoleProps')).to.deep.eq({
|
||||
Command: 'focused',
|
||||
Yielded: $input.get(0),
|
||||
Elements: 1,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('#consoleProps with null element', () => {
|
||||
const button = cy.$$('#button')
|
||||
|
||||
button.get(0).focus()
|
||||
button.get(0).blur()
|
||||
|
||||
cy.focused().should('not.exist').then(function () {
|
||||
expect(this.lastLog.invoke('consoleProps')).to.deep.eq({
|
||||
Command: 'focused',
|
||||
Yielded: '--nothing--',
|
||||
Elements: 0,
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('errors', {
|
||||
defaultCommandTimeout: 100,
|
||||
}, () => {
|
||||
beforeEach(function () {
|
||||
this.logs = []
|
||||
|
||||
cy.on('log:added', (attrs, log) => {
|
||||
this.lastLog = log
|
||||
|
||||
this.logs.push(log)
|
||||
})
|
||||
|
||||
return null
|
||||
})
|
||||
|
||||
it('fails waiting for the element to exist', (done) => {
|
||||
const button = cy.$$('#button')
|
||||
|
||||
button.get(0).focus()
|
||||
button.get(0).blur()
|
||||
|
||||
cy.on('fail', (err) => {
|
||||
expect(err.message).to.include('Expected to find element: `focused`, but never found it.')
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
cy.focused()
|
||||
})
|
||||
|
||||
it('fails waiting for the focused element not to exist', (done) => {
|
||||
cy.$$('input:first').focus()
|
||||
|
||||
cy.on('fail', (err) => {
|
||||
expect(err.message).to.include('Expected <input#input> not to exist in the DOM, but it was continuously found.')
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
cy.focused().should('not.exist')
|
||||
})
|
||||
|
||||
it('eventually fails the assertion', function (done) {
|
||||
cy.$$('input:first').focus()
|
||||
|
||||
cy.on('fail', (err) => {
|
||||
const { lastLog } = this
|
||||
|
||||
expect(err.message).to.include(lastLog.get('error').message)
|
||||
expect(err.message).not.to.include('undefined')
|
||||
expect(lastLog.get('name')).to.eq('assert')
|
||||
expect(lastLog.get('state')).to.eq('failed')
|
||||
expect(lastLog.get('error')).to.be.an.instanceof(chai.AssertionError)
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
cy.focused().should('have.class', 'focused')
|
||||
})
|
||||
|
||||
it('does not log an additional log on failure', function (done) {
|
||||
cy.on('fail', () => {
|
||||
assertLogLength(this.logs, 2)
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
cy.focused().should('have.class', 'focused')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -7,331 +7,6 @@ describe('src/cy/commands/querying', () => {
|
||||
cy.visit('/fixtures/dom.html')
|
||||
})
|
||||
|
||||
context('#focused', () => {
|
||||
it('returns the activeElement', () => {
|
||||
const $button = cy.$$('#button')
|
||||
|
||||
$button.get(0).focus()
|
||||
|
||||
expect(cy.state('document').activeElement).to.eq($button.get(0))
|
||||
|
||||
cy.focused().then(($focused) => {
|
||||
expect($focused.get(0)).to.eq($button.get(0))
|
||||
})
|
||||
})
|
||||
|
||||
it('returns null if no activeElement', () => {
|
||||
const $button = cy.$$('#button')
|
||||
|
||||
$button.get(0).focus()
|
||||
$button.get(0).blur()
|
||||
|
||||
cy.focused().should('not.exist').then(($focused) => {
|
||||
expect($focused).to.be.null
|
||||
})
|
||||
})
|
||||
|
||||
describe('assertion verification', () => {
|
||||
beforeEach(function () {
|
||||
cy.on('log:added', (attrs, log) => {
|
||||
if (log.get('name') === 'assert') {
|
||||
this.lastLog = log
|
||||
}
|
||||
})
|
||||
|
||||
return null
|
||||
})
|
||||
|
||||
it('eventually passes the assertion', () => {
|
||||
cy.on('command:retry', _.after(2, () => {
|
||||
cy.$$(':text:first').addClass('focused').focus()
|
||||
}))
|
||||
|
||||
cy.focused().should('have.class', 'focused').then(function () {
|
||||
const { lastLog } = this
|
||||
|
||||
expect(lastLog.get('name')).to.eq('assert')
|
||||
expect(lastLog.get('state')).to.eq('passed')
|
||||
|
||||
expect(lastLog.get('ended')).to.be.true
|
||||
})
|
||||
})
|
||||
|
||||
// https://github.com/cypress-io/cypress/issues/409
|
||||
it('retries on an elements value', () => {
|
||||
const $input = cy.$$('input:first')
|
||||
|
||||
cy.on('command:retry', _.after(2, () => {
|
||||
$input.val('1234')
|
||||
|
||||
$input.get(0).focus()
|
||||
}))
|
||||
|
||||
cy.focused().should('have.value', '1234').then(function () {
|
||||
const { lastLog } = this
|
||||
|
||||
expect(lastLog.get('name')).to.eq('assert')
|
||||
expect(lastLog.get('state')).to.eq('passed')
|
||||
|
||||
expect(lastLog.get('ended')).to.be.true
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('.log', () => {
|
||||
beforeEach(function () {
|
||||
cy.$$('input:first').get(0).focus()
|
||||
|
||||
cy.on('log:added', (attrs, log) => {
|
||||
if (log.get('name') === 'focused') {
|
||||
this.lastLog = log
|
||||
}
|
||||
})
|
||||
|
||||
return null
|
||||
})
|
||||
|
||||
it('is a parent command', () => {
|
||||
cy.get('body').focused().then(function () {
|
||||
const { lastLog } = this
|
||||
|
||||
expect(lastLog.get('type')).to.eq('parent')
|
||||
})
|
||||
})
|
||||
|
||||
it('ends immediately', () => {
|
||||
cy.focused().then(function () {
|
||||
const { lastLog } = this
|
||||
|
||||
expect(lastLog.get('ended')).to.be.true
|
||||
|
||||
expect(lastLog.get('state')).to.eq('passed')
|
||||
})
|
||||
})
|
||||
|
||||
it('snapshots immediately', () => {
|
||||
cy.focused().then(function () {
|
||||
const { lastLog } = this
|
||||
|
||||
expect(lastLog.get('snapshots').length).to.eq(1)
|
||||
|
||||
expect(lastLog.get('snapshots')[0]).to.be.an('object')
|
||||
})
|
||||
})
|
||||
|
||||
it('passes in $el', () => {
|
||||
cy.get('input:first').focused().then(function ($input) {
|
||||
const { lastLog } = this
|
||||
|
||||
expect(lastLog.get('$el')).to.eq($input)
|
||||
})
|
||||
})
|
||||
|
||||
it('#consoleProps', () => {
|
||||
cy.get('input:first').focused().then(function ($input) {
|
||||
expect(this.lastLog.invoke('consoleProps')).to.deep.eq({
|
||||
Command: 'focused',
|
||||
Yielded: $input.get(0),
|
||||
Elements: 1,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('#consoleProps with null element', () => {
|
||||
const button = cy.$$('#button')
|
||||
|
||||
button.get(0).focus()
|
||||
button.get(0).blur()
|
||||
|
||||
cy.focused().should('not.exist').then(function () {
|
||||
expect(this.lastLog.invoke('consoleProps')).to.deep.eq({
|
||||
Command: 'focused',
|
||||
Yielded: '--nothing--',
|
||||
Elements: 0,
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('errors', {
|
||||
defaultCommandTimeout: 100,
|
||||
}, () => {
|
||||
beforeEach(function () {
|
||||
this.logs = []
|
||||
|
||||
cy.on('log:added', (attrs, log) => {
|
||||
this.lastLog = log
|
||||
|
||||
this.logs.push(log)
|
||||
})
|
||||
|
||||
return null
|
||||
})
|
||||
|
||||
it('fails waiting for the element to exist', (done) => {
|
||||
const button = cy.$$('#button')
|
||||
|
||||
button.get(0).focus()
|
||||
button.get(0).blur()
|
||||
|
||||
cy.on('fail', (err) => {
|
||||
expect(err.message).to.include('Expected to find element: `focused`, but never found it.')
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
cy.focused()
|
||||
})
|
||||
|
||||
it('fails waiting for the focused element not to exist', (done) => {
|
||||
cy.$$('input:first').focus()
|
||||
|
||||
cy.on('fail', (err) => {
|
||||
expect(err.message).to.include('Expected <input#input> not to exist in the DOM, but it was continuously found.')
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
cy.focused().should('not.exist')
|
||||
})
|
||||
|
||||
it('eventually fails the assertion', function (done) {
|
||||
cy.$$('input:first').focus()
|
||||
|
||||
cy.on('fail', (err) => {
|
||||
const { lastLog } = this
|
||||
|
||||
expect(err.message).to.include(lastLog.get('error').message)
|
||||
expect(err.message).not.to.include('undefined')
|
||||
expect(lastLog.get('name')).to.eq('assert')
|
||||
expect(lastLog.get('state')).to.eq('failed')
|
||||
expect(lastLog.get('error')).to.be.an.instanceof(chai.AssertionError)
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
cy.focused().should('have.class', 'focused')
|
||||
})
|
||||
|
||||
it('does not log an additional log on failure', function (done) {
|
||||
cy.on('fail', () => {
|
||||
assertLogLength(this.logs, 2)
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
cy.focused().should('have.class', 'focused')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
context('#root', () => {
|
||||
it('returns html', () => {
|
||||
const html = cy.$$('html')
|
||||
|
||||
cy.root().then(($html) => {
|
||||
expect($html.get(0)).to.eq(html.get(0))
|
||||
})
|
||||
})
|
||||
|
||||
it('returns withinSubject if exists', () => {
|
||||
const form = cy.$$('form')
|
||||
|
||||
cy.get('form').within(() => {
|
||||
cy
|
||||
.get('input')
|
||||
.root().then(($root) => {
|
||||
expect($root.get(0)).to.eq(form.get(0))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('eventually resolves', () => {
|
||||
_.delay(() => {
|
||||
cy.$$('html').addClass('foo').addClass('bar')
|
||||
}
|
||||
, 100)
|
||||
|
||||
cy.root().should('have.class', 'foo').and('have.class', 'bar')
|
||||
})
|
||||
|
||||
describe('.log', () => {
|
||||
beforeEach(function () {
|
||||
this.logs = []
|
||||
|
||||
cy.on('log:added', (attrs, log) => {
|
||||
if (attrs.name === 'root') {
|
||||
this.lastLog = log
|
||||
|
||||
this.logs.push(log)
|
||||
}
|
||||
})
|
||||
|
||||
return null
|
||||
})
|
||||
|
||||
it('can turn off logging', () => {
|
||||
cy.root({ log: false }).then(function () {
|
||||
expect(this.log).to.be.undefined
|
||||
})
|
||||
})
|
||||
|
||||
it('logs immediately before resolving', (done) => {
|
||||
cy.on('log:added', (attrs, log) => {
|
||||
if (log.get('name') === 'root') {
|
||||
expect(log.get('state')).to.eq('pending')
|
||||
expect(log.get('message')).to.eq('')
|
||||
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
||||
cy.root()
|
||||
})
|
||||
|
||||
it('snapshots after clicking', () => {
|
||||
cy.root().then(function () {
|
||||
const { lastLog } = this
|
||||
|
||||
expect(lastLog.get('snapshots').length).to.eq(1)
|
||||
|
||||
expect(lastLog.get('snapshots')[0]).to.be.an('object')
|
||||
})
|
||||
})
|
||||
|
||||
it('sets $el to document', () => {
|
||||
const html = cy.$$('html')
|
||||
|
||||
cy.root().then(function () {
|
||||
expect(this.lastLog.get('$el').get(0)).to.eq(html.get(0))
|
||||
})
|
||||
})
|
||||
|
||||
it('sets $el to withinSubject', () => {
|
||||
const form = cy.$$('form')
|
||||
|
||||
cy.get('form').within(() => {
|
||||
cy
|
||||
.get('input')
|
||||
.root().then(function ($root) {
|
||||
expect(this.lastLog.get('$el').get(0)).to.eq(form.get(0))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('consoleProps', () => {
|
||||
cy.root().then(function ($root) {
|
||||
const consoleProps = this.lastLog.invoke('consoleProps')
|
||||
|
||||
expect(consoleProps).to.deep.eq({
|
||||
Command: 'root',
|
||||
Yielded: $root.get(0),
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
context('#get', {
|
||||
defaultCommandTimeout: 200,
|
||||
}, () => {
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
const { _ } = Cypress
|
||||
|
||||
describe('src/cy/commands/querying', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/fixtures/dom.html')
|
||||
})
|
||||
|
||||
context('#root', () => {
|
||||
it('returns html', () => {
|
||||
const html = cy.$$('html')
|
||||
|
||||
cy.root().then(($html) => {
|
||||
expect($html.get(0)).to.eq(html.get(0))
|
||||
})
|
||||
})
|
||||
|
||||
it('returns withinSubject if exists', () => {
|
||||
const form = cy.$$('form')
|
||||
|
||||
cy.get('form').within(() => {
|
||||
cy
|
||||
.get('input')
|
||||
.root().then(($root) => {
|
||||
expect($root.get(0)).to.eq(form.get(0))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('eventually resolves', () => {
|
||||
_.delay(() => {
|
||||
cy.$$('html').addClass('foo').addClass('bar')
|
||||
}
|
||||
, 100)
|
||||
|
||||
cy.root().should('have.class', 'foo').and('have.class', 'bar')
|
||||
})
|
||||
|
||||
describe('.log', () => {
|
||||
beforeEach(function () {
|
||||
this.logs = []
|
||||
|
||||
cy.on('log:added', (attrs, log) => {
|
||||
if (attrs.name === 'root') {
|
||||
this.lastLog = log
|
||||
|
||||
this.logs.push(log)
|
||||
}
|
||||
})
|
||||
|
||||
return null
|
||||
})
|
||||
|
||||
it('can turn off logging', () => {
|
||||
cy.root({ log: false }).then(function () {
|
||||
expect(this.log).to.be.undefined
|
||||
})
|
||||
})
|
||||
|
||||
it('logs immediately before resolving', (done) => {
|
||||
cy.on('log:added', (attrs, log) => {
|
||||
if (log.get('name') === 'root') {
|
||||
expect(log.get('state')).to.eq('pending')
|
||||
expect(log.get('message')).to.eq('')
|
||||
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
||||
cy.root()
|
||||
})
|
||||
|
||||
it('snapshots after clicking', () => {
|
||||
cy.root().then(function () {
|
||||
const { lastLog } = this
|
||||
|
||||
expect(lastLog.get('snapshots').length).to.eq(1)
|
||||
|
||||
expect(lastLog.get('snapshots')[0]).to.be.an('object')
|
||||
})
|
||||
})
|
||||
|
||||
it('sets $el to document', () => {
|
||||
const html = cy.$$('html')
|
||||
|
||||
cy.root().then(function () {
|
||||
expect(this.lastLog.get('$el').get(0)).to.eq(html.get(0))
|
||||
})
|
||||
})
|
||||
|
||||
it('sets $el to withinSubject', () => {
|
||||
const form = cy.$$('form')
|
||||
|
||||
cy.get('form').within(() => {
|
||||
cy
|
||||
.get('input')
|
||||
.root().then(function ($root) {
|
||||
expect(this.lastLog.get('$el').get(0)).to.eq(form.get(0))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('consoleProps', () => {
|
||||
cy.root().then(function ($root) {
|
||||
const consoleProps = this.lastLog.invoke('consoleProps')
|
||||
|
||||
expect(consoleProps).to.deep.eq({
|
||||
Command: 'root',
|
||||
Yielded: $root.get(0),
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -1,11 +1,17 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import $ from 'jquery'
|
||||
import JQuery from 'jquery'
|
||||
import _ from 'lodash'
|
||||
|
||||
import { scrollTo } from './jquery.scrollto'
|
||||
import $dom from '../dom'
|
||||
|
||||
// Add missing types.
|
||||
interface ExtendedJQueryStatic extends JQueryStatic {
|
||||
find: any
|
||||
expr: JQuery.Selectors & { filters: any }
|
||||
}
|
||||
|
||||
const $: ExtendedJQueryStatic = JQuery as any
|
||||
|
||||
// force jquery to have the same visible
|
||||
// and hidden logic as cypress
|
||||
|
||||
|
||||
@@ -54,6 +54,18 @@ export function create (chai) {
|
||||
typeof object.nodeName === 'string'
|
||||
}
|
||||
|
||||
// We can't just check if object instanceof ShadowRoot, because it might be the document of an iframe,
|
||||
// which in Chrome 99+ is a separate class, and instanceof ShadowRoot returns false.
|
||||
const isShadowRoot = function (object) {
|
||||
return isDOMElement(object.host) && object.host.shadowRoot === object
|
||||
}
|
||||
|
||||
// We can't just check if object instanceof Document, because it might be the document of an iframe,
|
||||
// which in Chrome 99+ is a separate class, and instanceof Document returns false.
|
||||
const isDocument = function (object) {
|
||||
return object.defaultView && object.defaultView === object.defaultView.window
|
||||
}
|
||||
|
||||
let formatValueHook
|
||||
|
||||
const setFormatValueHook = (fn) => formatValueHook = fn
|
||||
@@ -124,6 +136,14 @@ export function create (chai) {
|
||||
}
|
||||
}
|
||||
|
||||
if (isShadowRoot(value)) {
|
||||
return value.innerHTML
|
||||
}
|
||||
|
||||
if (isDocument(value)) {
|
||||
return value.documentElement.outerHTML
|
||||
}
|
||||
|
||||
// Look up the keys of the object.
|
||||
let visibleKeys = getEnumerableProperties(value)
|
||||
let keys = ctx.showHidden ? getProperties(value) : visibleKeys
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// @ts-nocheck
|
||||
import _ from 'lodash'
|
||||
import Promise from 'bluebird'
|
||||
|
||||
@@ -7,7 +6,7 @@ import $utils from '../../../cypress/utils'
|
||||
import $errUtils from '../../../cypress/error_utils'
|
||||
import $elements from '../../../dom/elements'
|
||||
|
||||
const checkOrUncheck = (Cypress, cy, type, subject, values = [], userOptions = {}) => {
|
||||
const checkOrUncheck = (Cypress, cy, type, subject, values: any[] = [], userOptions = {}) => {
|
||||
// we're not handling conversion of values to strings
|
||||
// in case we've received numbers
|
||||
|
||||
@@ -18,15 +17,15 @@ const checkOrUncheck = (Cypress, cy, type, subject, values = [], userOptions = {
|
||||
values = []
|
||||
} else {
|
||||
// make sure we're an array of values
|
||||
values = [].concat(values)
|
||||
values = ([] as any[]).concat(values)
|
||||
}
|
||||
|
||||
// keep an array of subjects which
|
||||
// are potentially reduced down
|
||||
// to new filtered subjects
|
||||
const matchingElements = []
|
||||
const matchingElements: HTMLElement[] = []
|
||||
|
||||
const options = _.defaults({}, userOptions, {
|
||||
const options: Record<string, any> = _.defaults({}, userOptions, {
|
||||
$el: subject,
|
||||
log: true,
|
||||
force: false,
|
||||
@@ -75,7 +74,7 @@ const checkOrUncheck = (Cypress, cy, type, subject, values = [], userOptions = {
|
||||
matchingElements.push(el)
|
||||
}
|
||||
|
||||
const consoleProps = {
|
||||
const consoleProps: Record<string, any> = {
|
||||
'Applied To': $dom.getElements($el),
|
||||
'Elements': $el.length,
|
||||
}
|
||||
|
||||
@@ -252,6 +252,8 @@ export default (Commands, Cypress, cy) => {
|
||||
interval: options.interval,
|
||||
})
|
||||
}).then(() => {
|
||||
const oldValue = options.$el[0].selectedIndex
|
||||
|
||||
// reset the selects value after we've
|
||||
// fired all the proper click events
|
||||
// for the options
|
||||
@@ -279,6 +281,12 @@ export default (Commands, Cypress, cy) => {
|
||||
options.$el[0].selectedIndex = selectedIndex
|
||||
}
|
||||
|
||||
// https://github.com/cypress-io/cypress/issues/19494
|
||||
// When user selects the same option again, `input`, `change` events should not be fired.
|
||||
if (options.$el[0].selectedIndex === oldValue) {
|
||||
return
|
||||
}
|
||||
|
||||
const input = new Event('input', {
|
||||
bubbles: true,
|
||||
cancelable: false,
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import _ from 'lodash'
|
||||
import Promise from 'bluebird'
|
||||
|
||||
@@ -59,7 +57,7 @@ export default (Commands, Cypress, cy, state, config) => {
|
||||
|
||||
({ options: userOptions, position, x, y } = $actionability.getPositionFromArguments(positionOrX, y, userOptions))
|
||||
|
||||
const options = _.defaults({}, userOptions, {
|
||||
const options: Record<string, any> = _.defaults({}, userOptions, {
|
||||
log: true,
|
||||
$el: subject,
|
||||
bubbles: true,
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// @ts-nocheck
|
||||
import _ from 'lodash'
|
||||
import Promise from 'bluebird'
|
||||
|
||||
@@ -15,7 +14,11 @@ const debug = debugFn('cypress:driver:command:type')
|
||||
export default function (Commands, Cypress, cy, state, config) {
|
||||
const { keyboard } = cy.devices
|
||||
|
||||
function type (subject, chars, options = {}) {
|
||||
// Note: These "change type of `any` to X" comments are written instead of changing them directly
|
||||
// because Cypress extends user-given options with Cypress internal options.
|
||||
// These comments will be removed after removing `// @ts-nocheck` comments in `packages/driver`.
|
||||
// TODO: change the type of `any` to `Partial<Cypress.TypeOptions>`
|
||||
function type (subject, chars, options: any = {}) {
|
||||
const userOptions = options
|
||||
let updateTable
|
||||
|
||||
@@ -277,6 +280,13 @@ export default function (Commands, Cypress, cy, state, config) {
|
||||
const type = (type) => $elements.isInputType(options.$el.get(0), type)
|
||||
const sendClickEvent = type('button') || type('image') || type('submit') || type('reset')
|
||||
|
||||
const fireClickEvent = (el) => {
|
||||
const ctor = $dom.getDocumentFromElement(el).defaultView!.PointerEvent
|
||||
const event = new ctor('click')
|
||||
|
||||
el.dispatchEvent(event)
|
||||
}
|
||||
|
||||
return keyboard.type({
|
||||
$el: options.$el,
|
||||
chars,
|
||||
@@ -317,7 +327,28 @@ export default function (Commands, Cypress, cy, state, config) {
|
||||
}
|
||||
},
|
||||
|
||||
onEvent: updateTable || _.noop,
|
||||
onEvent (id, key, event, value) {
|
||||
if (updateTable) {
|
||||
updateTable(id, key, event, value)
|
||||
}
|
||||
|
||||
if (
|
||||
// Firefox sends a click event when the Space key is pressed.
|
||||
// We don't want send it twice.
|
||||
!Cypress.isBrowser('firefox') &&
|
||||
// Click event is sent after keyup event with space key.
|
||||
event.type === 'keyup' && event.code === 'Space' &&
|
||||
// Click events should be only sent to button-like elements.
|
||||
// event.target is null when used with shadow DOM.
|
||||
(event.target && $elements.isButtonLike(event.target)) &&
|
||||
// When a space key is pressed for input radio elements, the click event is only fired when it's not checked.
|
||||
!(event.target.tagName === 'INPUT' && event.target.type === 'radio' && event.target.checked === true) &&
|
||||
// When event is prevented, the click event should not be emitted
|
||||
!event.defaultPrevented
|
||||
) {
|
||||
fireClickEvent(event.target)
|
||||
}
|
||||
},
|
||||
|
||||
// fires only when the 'value'
|
||||
// of input/text/contenteditable
|
||||
@@ -365,10 +396,7 @@ export default function (Commands, Cypress, cy, state, config) {
|
||||
if (sendClickEvent) {
|
||||
// Firefox sends a click event automatically.
|
||||
if (!Cypress.isBrowser('firefox')) {
|
||||
const ctor = $dom.getDocumentFromElement(el).defaultView?.PointerEvent
|
||||
const event = new ctor('click')
|
||||
|
||||
el.dispatchEvent(event)
|
||||
fireClickEvent(el)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -510,7 +538,8 @@ export default function (Commands, Cypress, cy, state, config) {
|
||||
})
|
||||
}
|
||||
|
||||
function clear (subject, options = {}) {
|
||||
// TODO: change the type of `any` to `Partial<ClearOptions>`
|
||||
function clear (subject, options: any = {}) {
|
||||
const userOptions = options
|
||||
|
||||
options = _.defaults({}, userOptions, {
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import _ from 'lodash'
|
||||
import Promise from 'bluebird'
|
||||
|
||||
import $dom from '../../dom'
|
||||
import $utils from '../../cypress/utils'
|
||||
import $errUtils from '../../cypress/error_utils'
|
||||
import $errUtils, { CypressError } from '../../cypress/error_utils'
|
||||
|
||||
const returnFalseIfThenable = (key, ...args) => {
|
||||
const returnFalseIfThenable = (key, ...args): boolean => {
|
||||
if ((key === 'then') && _.isFunction(args[0]) && _.isFunction(args[1])) {
|
||||
// https://github.com/cypress-io/cypress/issues/111
|
||||
// if we're inside of a promise then the promise lib will naturally
|
||||
@@ -22,6 +20,8 @@ const returnFalseIfThenable = (key, ...args) => {
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
const primitiveToObject = (memo) => {
|
||||
@@ -181,7 +181,7 @@ export default function (Commands, Cypress, cy, state) {
|
||||
|
||||
const invokeFn = (subject, userOptionsOrStr, ...args) => {
|
||||
const userOptionsPassed = _.isObject(userOptionsOrStr) && !_.isFunction(userOptionsOrStr)
|
||||
let userOptions = null
|
||||
let userOptions: Record<string, any> | null = null
|
||||
let str = null
|
||||
|
||||
if (!userOptionsPassed) {
|
||||
@@ -219,7 +219,7 @@ export default function (Commands, Cypress, cy, state) {
|
||||
|
||||
const message = getMessage()
|
||||
|
||||
let traversalErr = null
|
||||
let traversalErr: CypressError | null = null
|
||||
|
||||
// copy userOptions because _log is added below.
|
||||
const options = _.extend({}, userOptions)
|
||||
@@ -568,7 +568,7 @@ export default function (Commands, Cypress, cy, state) {
|
||||
return ret
|
||||
}
|
||||
|
||||
return thenFn(el, userOptions, callback, state)
|
||||
return thenFn(el, userOptions, callback)
|
||||
}
|
||||
|
||||
// generate a real array since bluebird is finicky and
|
||||
@@ -586,9 +586,9 @@ export default function (Commands, Cypress, cy, state) {
|
||||
// cy.resolve + cy.wrap are upgraded to handle
|
||||
// promises
|
||||
Commands.addAll({ prevSubject: 'optional' }, {
|
||||
then () {
|
||||
then (subject, userOptions, fn) {
|
||||
// eslint-disable-next-line prefer-rest-params
|
||||
return thenFn.apply(this, arguments)
|
||||
return thenFn.apply(this, [subject, userOptions, fn])
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import _ from 'lodash'
|
||||
import Promise from 'bluebird'
|
||||
|
||||
@@ -110,7 +108,7 @@ export default function (Commands, Cypress, cy, state, config) {
|
||||
})
|
||||
}
|
||||
|
||||
const getAndClear = (log, timeout, options = {}) => {
|
||||
const getAndClear = (log?, timeout?, options = {}) => {
|
||||
return automateCookies('get:cookies', options, log, timeout)
|
||||
.then((resp) => {
|
||||
// bail early if we got no cookies!
|
||||
@@ -166,7 +164,8 @@ export default function (Commands, Cypress, cy, state, config) {
|
||||
})
|
||||
|
||||
return Commands.addAll({
|
||||
getCookie (name, options = {}) {
|
||||
// TODO: change the type of `any` to `Partial<Cypress.Loggable & Cypress.Timeoutable>`
|
||||
getCookie (name, options: any = {}) {
|
||||
const userOptions = options
|
||||
|
||||
options = _.defaults({}, userOptions, {
|
||||
@@ -212,7 +211,8 @@ export default function (Commands, Cypress, cy, state, config) {
|
||||
.catch(handleBackendError('getCookie', 'reading the requested cookie from', onFail))
|
||||
},
|
||||
|
||||
getCookies (options = {}) {
|
||||
// TODO: change the type of `any` to `Partial<Cypress.Loggable & Cypress.Timeoutable>`
|
||||
getCookies (options: any = {}) {
|
||||
const userOptions = options
|
||||
|
||||
options = _.defaults({}, userOptions, {
|
||||
@@ -250,7 +250,8 @@ export default function (Commands, Cypress, cy, state, config) {
|
||||
.catch(handleBackendError('getCookies', 'reading cookies from', options._log))
|
||||
},
|
||||
|
||||
setCookie (name, value, options = {}) {
|
||||
// TODO: change the type of `any` to `Partial<Cypress.SetCookieOptions>`
|
||||
setCookie (name, value, options: any = {}) {
|
||||
const userOptions = options
|
||||
|
||||
options = _.defaults({}, userOptions, {
|
||||
@@ -331,7 +332,8 @@ export default function (Commands, Cypress, cy, state, config) {
|
||||
}).catch(handleBackendError('setCookie', 'setting the requested cookie in', onFail))
|
||||
},
|
||||
|
||||
clearCookie (name, options = {}) {
|
||||
// TODO: change the type of `any` to `Partial<Cypress.Loggable & Cypress.Timeoutable>`
|
||||
clearCookie (name, options: any = {}) {
|
||||
const userOptions = options
|
||||
|
||||
options = _.defaults({}, userOptions, {
|
||||
@@ -380,7 +382,8 @@ export default function (Commands, Cypress, cy, state, config) {
|
||||
.catch(handleBackendError('clearCookie', 'clearing the requested cookie in', onFail))
|
||||
},
|
||||
|
||||
clearCookies (options = {}) {
|
||||
// TODO: change the type of `any` to `Partial<Cypress.Loggable & Cypress.Timeoutable>`
|
||||
clearCookies (options: any = {}) {
|
||||
const userOptions = options
|
||||
|
||||
options = _.defaults({}, userOptions, {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import _ from 'lodash'
|
||||
import Promise from 'bluebird'
|
||||
|
||||
@@ -7,7 +5,8 @@ import $errUtils from '../../cypress/error_utils'
|
||||
|
||||
export default (Commands, Cypress, cy) => {
|
||||
Commands.addAll({
|
||||
exec (cmd, options = {}) {
|
||||
// TODO: change the type of `any` to `Partical<Cypress.ExecOptions>`
|
||||
exec (cmd, options: any = {}) {
|
||||
const userOptions = options
|
||||
|
||||
options = _.defaults({}, userOptions, {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// @ts-nocheck
|
||||
import _ from 'lodash'
|
||||
import { basename } from 'path'
|
||||
|
||||
@@ -6,7 +5,8 @@ import $errUtils from '../../cypress/error_utils'
|
||||
|
||||
export default (Commands, Cypress, cy, state) => {
|
||||
Commands.addAll({
|
||||
readFile (file, encoding, options = {}) {
|
||||
// TODO: change the type of `any` to `Partial<Cypress.Loggable & Cypress.Timeoutable>`
|
||||
readFile (file, encoding, options: any = {}) {
|
||||
let userOptions = options
|
||||
|
||||
if (_.isObject(encoding)) {
|
||||
@@ -109,7 +109,8 @@ export default (Commands, Cypress, cy, state) => {
|
||||
return verifyAssertions()
|
||||
},
|
||||
|
||||
writeFile (fileName, contents, encoding, options = {}) {
|
||||
// TODO: change the type of `any` to `Partial<Cypress.WriteFileOPtions & Cypress.Timeoutable>`
|
||||
writeFile (fileName, contents, encoding, options: any = {}) {
|
||||
let userOptions = options
|
||||
|
||||
if (_.isObject(encoding)) {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import _ from 'lodash'
|
||||
import Promise from 'bluebird'
|
||||
import { basename } from 'path'
|
||||
@@ -44,7 +42,7 @@ export default (Commands, Cypress, cy, state, config) => {
|
||||
return Promise.resolve(clone(resp))
|
||||
}
|
||||
|
||||
let options = {}
|
||||
let options: Record<string, any> = {}
|
||||
|
||||
if (_.isObject(args[0])) {
|
||||
options = args[0]
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import _ from 'lodash'
|
||||
import Promise from 'bluebird'
|
||||
|
||||
@@ -8,7 +6,8 @@ const { throwErrByPath } = $errUtils
|
||||
|
||||
export default (Commands, Cypress, cy) => {
|
||||
Commands.addAll({
|
||||
url (options = {}) {
|
||||
// TODO: change the type of `any` to `Partial<Cypress.UrlOptions>`
|
||||
url (options: any = {}) {
|
||||
const userOptions = options
|
||||
|
||||
options = _.defaults({}, userOptions, { log: true })
|
||||
@@ -39,7 +38,8 @@ export default (Commands, Cypress, cy) => {
|
||||
return resolveHref()
|
||||
},
|
||||
|
||||
hash (options = {}) {
|
||||
// TODO: change the type of `any` to `Partial<Cypress.Loggable & Cypress.Timeoutable>`
|
||||
hash (options: any = {}) {
|
||||
const userOptions = options
|
||||
|
||||
options = _.defaults({}, userOptions, { log: true })
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// @ts-nocheck
|
||||
import _ from 'lodash'
|
||||
import Promise from 'bluebird'
|
||||
|
||||
@@ -50,7 +49,8 @@ export default (Commands, Cypress, cy, state) => {
|
||||
return null
|
||||
},
|
||||
|
||||
wrap (arg, options = {}) {
|
||||
// TODO: change the type of `any` to `Partial<Cypress.Loggable & Cypress.Timeoutable>`
|
||||
wrap (arg, options: any = {}) {
|
||||
const userOptions = options
|
||||
|
||||
options = _.defaults({}, userOptions, {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// @ts-nocheck
|
||||
/* global cy, Cypress */
|
||||
import _ from 'lodash'
|
||||
import whatIsCircular from '@cypress/what-is-circular'
|
||||
import UrlParse from 'url-parse'
|
||||
@@ -15,10 +13,10 @@ import debugFn from 'debug'
|
||||
const debug = debugFn('cypress:driver:navigation')
|
||||
|
||||
let id = null
|
||||
let previousDomainVisited = null
|
||||
let hasVisitedAboutBlank = null
|
||||
let currentlyVisitingAboutBlank = null
|
||||
let knownCommandCausedInstability = null
|
||||
let previousDomainVisited: boolean = false
|
||||
let hasVisitedAboutBlank: boolean = false
|
||||
let currentlyVisitingAboutBlank: boolean = false
|
||||
let knownCommandCausedInstability: boolean = false
|
||||
|
||||
const REQUEST_URL_OPTS = 'auth failOnStatusCode retryOnNetworkFailure retryOnStatusCodeFailure retryIntervals method body headers'
|
||||
.split(' ')
|
||||
@@ -27,7 +25,7 @@ const VISIT_OPTS = 'url log onBeforeLoad onLoad timeout requestTimeout'
|
||||
.split(' ')
|
||||
.concat(REQUEST_URL_OPTS)
|
||||
|
||||
const reset = (test = {}) => {
|
||||
const reset = (test: any = {}) => {
|
||||
knownCommandCausedInstability = false
|
||||
|
||||
// continuously reset this
|
||||
@@ -62,7 +60,7 @@ const timedOutWaitingForPageLoad = (ms, log) => {
|
||||
}
|
||||
|
||||
const cannotVisitDifferentOrigin = (origin, previousUrlVisited, remoteUrl, existingUrl, log) => {
|
||||
const differences = []
|
||||
const differences: string[] = []
|
||||
|
||||
if (remoteUrl.protocol !== existingUrl.protocol) {
|
||||
differences.push('protocol')
|
||||
@@ -171,7 +169,7 @@ const navigationChanged = (Cypress, cy, state, source, arg) => {
|
||||
end: true,
|
||||
snapshot: true,
|
||||
consoleProps () {
|
||||
const obj = {
|
||||
const obj: Record<string, any> = {
|
||||
'New Url': url,
|
||||
}
|
||||
|
||||
@@ -265,7 +263,7 @@ const stabilityChanged = (Cypress, state, config, stable) => {
|
||||
return
|
||||
}
|
||||
|
||||
const options = {}
|
||||
const options: Record<string, any> = {}
|
||||
|
||||
_.defaults(options, {
|
||||
timeout: config('pageLoadTimeout'),
|
||||
@@ -433,6 +431,14 @@ const normalizeTimeoutOptions = (options) => {
|
||||
.value()
|
||||
}
|
||||
|
||||
type NotOkResponseError = Error & {
|
||||
gotResponse: boolean
|
||||
}
|
||||
|
||||
type InvalidContentTypeError = Error & {
|
||||
invalidContentType: boolean
|
||||
}
|
||||
|
||||
export default (Commands, Cypress, cy, state, config) => {
|
||||
reset()
|
||||
|
||||
@@ -449,7 +455,7 @@ export default (Commands, Cypress, cy, state, config) => {
|
||||
Cypress.on('stability:changed', (bool, event) => {
|
||||
// only send up page loading events when we're
|
||||
// not stable!
|
||||
stabilityChanged(Cypress, state, config, bool, event)
|
||||
stabilityChanged(Cypress, state, config, bool)
|
||||
})
|
||||
|
||||
Cypress.on('navigation:changed', (source, arg) => {
|
||||
@@ -474,11 +480,11 @@ export default (Commands, Cypress, cy, state, config) => {
|
||||
url,
|
||||
normalizeTimeoutOptions(options),
|
||||
)
|
||||
.then((resp = {}) => {
|
||||
.then((resp: any = {}) => {
|
||||
if (!resp.isOkStatusCode) {
|
||||
// if we didn't even get an OK response
|
||||
// then immediately die
|
||||
const err = new Error
|
||||
const err: NotOkResponseError = new Error as any
|
||||
|
||||
err.gotResponse = true
|
||||
_.extend(err, resp)
|
||||
@@ -488,7 +494,7 @@ export default (Commands, Cypress, cy, state, config) => {
|
||||
|
||||
if (!resp.isHtml) {
|
||||
// throw invalid contentType error
|
||||
const err = new Error
|
||||
const err: InvalidContentTypeError = new Error as any
|
||||
|
||||
err.invalidContentType = true
|
||||
_.extend(err, resp)
|
||||
@@ -554,7 +560,7 @@ export default (Commands, Cypress, cy, state, config) => {
|
||||
// clear the current timeout
|
||||
cy.clearTimeout('reload')
|
||||
|
||||
let cleanup = null
|
||||
let cleanup: (() => any) | null = null
|
||||
const options = _.defaults({}, userOptions, {
|
||||
log: true,
|
||||
timeout: config('pageLoadTimeout'),
|
||||
@@ -608,7 +614,7 @@ export default (Commands, Cypress, cy, state, config) => {
|
||||
},
|
||||
|
||||
go (numberOrString, userOptions = {}) {
|
||||
const options = _.defaults({}, userOptions, {
|
||||
const options: Record<string, any> = _.defaults({}, userOptions, {
|
||||
log: true,
|
||||
timeout: config('pageLoadTimeout'),
|
||||
})
|
||||
@@ -624,7 +630,7 @@ export default (Commands, Cypress, cy, state, config) => {
|
||||
$errUtils.throwErrByPath('go.invalid_number', { onFail: options._log })
|
||||
}
|
||||
|
||||
let cleanup = null
|
||||
let cleanup: (() => any) | null = null
|
||||
|
||||
if (options._log) {
|
||||
options._log.snapshot('before', { next: 'after' })
|
||||
@@ -698,7 +704,7 @@ export default (Commands, Cypress, cy, state, config) => {
|
||||
case 'forward': return goNumber(1)
|
||||
case 'back': return goNumber(-1)
|
||||
default:
|
||||
$errUtils.throwErrByPath('go.invalid_direction', {
|
||||
return $errUtils.throwErrByPath('go.invalid_direction', {
|
||||
onFail: options._log,
|
||||
args: { str },
|
||||
})
|
||||
@@ -713,10 +719,11 @@ export default (Commands, Cypress, cy, state, config) => {
|
||||
return goString(numberOrString)
|
||||
}
|
||||
|
||||
$errUtils.throwErrByPath('go.invalid_argument', { onFail: options._log })
|
||||
return $errUtils.throwErrByPath('go.invalid_argument', { onFail: options._log })
|
||||
},
|
||||
|
||||
visit (url, options = {}) {
|
||||
// TODO: Change the type of `any` to `Partial<Cypress.VisitOptions>`.
|
||||
visit (url, options: any = {}) {
|
||||
if (options.url && url) {
|
||||
$errUtils.throwErrByPath('visit.no_duplicate_url', { args: { optionsUrl: options.url, url } })
|
||||
}
|
||||
@@ -807,7 +814,7 @@ export default (Commands, Cypress, cy, state, config) => {
|
||||
url = $Location.mergeUrlWithParams(url, qs)
|
||||
}
|
||||
|
||||
let cleanup = null
|
||||
let cleanup: (() => any) | null = null
|
||||
|
||||
// clear the current timeout
|
||||
cy.clearTimeout('visit')
|
||||
@@ -830,7 +837,7 @@ export default (Commands, Cypress, cy, state, config) => {
|
||||
})
|
||||
|
||||
options.onBeforeLoad?.call(runnable.ctx, contentWindow)
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
err.isCallbackError = true
|
||||
onBeforeLoadError = err
|
||||
}
|
||||
@@ -876,7 +883,10 @@ export default (Commands, Cypress, cy, state, config) => {
|
||||
})
|
||||
}
|
||||
|
||||
const onLoad = ({ runOnLoadCallback, totalTime }) => {
|
||||
const onLoad = ({ runOnLoadCallback, totalTime }: {
|
||||
runOnLoadCallback?: boolean
|
||||
totalTime?: number
|
||||
}) => {
|
||||
// reset window on load
|
||||
win = state('window')
|
||||
|
||||
@@ -884,7 +894,7 @@ export default (Commands, Cypress, cy, state, config) => {
|
||||
if (runOnLoadCallback !== false) {
|
||||
try {
|
||||
options.onLoad?.call(runnable.ctx, win)
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
// mark these as user callback errors, so they're treated differently
|
||||
// than Node.js errors when caught below
|
||||
err.isCallbackError = true
|
||||
@@ -959,7 +969,9 @@ export default (Commands, Cypress, cy, state, config) => {
|
||||
}
|
||||
|
||||
return changeIframeSrc(remote.href, 'hashchange')
|
||||
.then(onLoad)
|
||||
.then(() => {
|
||||
return onLoad({})
|
||||
})
|
||||
}
|
||||
|
||||
if (existingHash) {
|
||||
@@ -974,7 +986,7 @@ export default (Commands, Cypress, cy, state, config) => {
|
||||
}
|
||||
|
||||
return requestUrl(url, options)
|
||||
.then((resp = {}) => {
|
||||
.then((resp: any = {}) => {
|
||||
let { url, originalUrl, cookies, redirects, filePath } = resp
|
||||
|
||||
// reapply the existing hash
|
||||
@@ -1029,7 +1041,7 @@ export default (Commands, Cypress, cy, state, config) => {
|
||||
// tell our backend we're changing domains
|
||||
// TODO: add in other things we want to preserve
|
||||
// state for like scrollTop
|
||||
let s = {
|
||||
let s: Record<string, any> = {
|
||||
currentId: id,
|
||||
tests: Cypress.runner.getTestsState(),
|
||||
startTime: Cypress.runner.getStartTime(),
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
import _ from 'lodash'
|
||||
import Promise from 'bluebird'
|
||||
|
||||
import $dom from '../../../dom'
|
||||
|
||||
export default (Commands, Cypress, cy, state) => {
|
||||
Commands.addAll({
|
||||
// TODO: any -> Partial<Cypress.Loggable & Cypress.Timeoutable>
|
||||
focused (options: any = {}) {
|
||||
const userOptions = options
|
||||
|
||||
options = _.defaults({}, userOptions, {
|
||||
verify: true,
|
||||
log: true,
|
||||
})
|
||||
|
||||
if (options.log) {
|
||||
options._log = Cypress.log({ timeout: options.timeout })
|
||||
}
|
||||
|
||||
const log = ($el) => {
|
||||
if (options.log === false) {
|
||||
return
|
||||
}
|
||||
|
||||
options._log.set({
|
||||
$el,
|
||||
consoleProps () {
|
||||
const ret = $el ? $dom.getElements($el) : '--nothing--'
|
||||
|
||||
return {
|
||||
Yielded: ret,
|
||||
Elements: $el != null ? $el.length : 0,
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const getFocused = () => {
|
||||
const focused = cy.getFocused()
|
||||
|
||||
log(focused)
|
||||
|
||||
return focused
|
||||
}
|
||||
|
||||
const resolveFocused = () => {
|
||||
return Promise
|
||||
.try(getFocused)
|
||||
.then(($el) => {
|
||||
if (options.verify === false) {
|
||||
return $el
|
||||
}
|
||||
|
||||
if (!$el) {
|
||||
$el = $dom.wrap(null)
|
||||
$el.selector = 'focused'
|
||||
}
|
||||
|
||||
// pass in a null jquery object for assertions
|
||||
return cy.verifyUpcomingAssertions($el, options, {
|
||||
onRetry: resolveFocused,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
return resolveFocused()
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -1,7 +1,11 @@
|
||||
import * as Focused from './focused'
|
||||
import * as Querying from './querying'
|
||||
import * as Root from './root'
|
||||
import * as Within from './within'
|
||||
|
||||
export {
|
||||
Focused,
|
||||
Querying,
|
||||
Root,
|
||||
Within,
|
||||
}
|
||||
|
||||
@@ -9,68 +9,6 @@ import { getAliasedRequests, isDynamicAliasingPossible } from '../../net-stubbin
|
||||
|
||||
export default (Commands, Cypress, cy, state) => {
|
||||
Commands.addAll({
|
||||
// TODO: any -> Partial<Cypress.Loggable & Cypress.Timeoutable>
|
||||
focused (options: any = {}) {
|
||||
const userOptions = options
|
||||
|
||||
options = _.defaults({}, userOptions, {
|
||||
verify: true,
|
||||
log: true,
|
||||
})
|
||||
|
||||
if (options.log) {
|
||||
options._log = Cypress.log({ timeout: options.timeout })
|
||||
}
|
||||
|
||||
const log = ($el) => {
|
||||
if (options.log === false) {
|
||||
return
|
||||
}
|
||||
|
||||
options._log.set({
|
||||
$el,
|
||||
consoleProps () {
|
||||
const ret = $el ? $dom.getElements($el) : '--nothing--'
|
||||
|
||||
return {
|
||||
Yielded: ret,
|
||||
Elements: $el != null ? $el.length : 0,
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const getFocused = () => {
|
||||
const focused = cy.getFocused()
|
||||
|
||||
log(focused)
|
||||
|
||||
return focused
|
||||
}
|
||||
|
||||
const resolveFocused = () => {
|
||||
return Promise
|
||||
.try(getFocused)
|
||||
.then(($el) => {
|
||||
if (options.verify === false) {
|
||||
return $el
|
||||
}
|
||||
|
||||
if (!$el) {
|
||||
$el = $dom.wrap(null)
|
||||
$el.selector = 'focused'
|
||||
}
|
||||
|
||||
// pass in a null jquery object for assertions
|
||||
return cy.verifyUpcomingAssertions($el, options, {
|
||||
onRetry: resolveFocused,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
return resolveFocused()
|
||||
},
|
||||
|
||||
// TODO: any -> Partial<Cypress.Loggable & Cypress.Timeoutable & Cypress.Withinable & Cypress.Shadow>
|
||||
get (selector, options: any = {}) {
|
||||
const userOptions = options
|
||||
@@ -409,36 +347,6 @@ export default (Commands, Cypress, cy, state) => {
|
||||
|
||||
return resolveElements()
|
||||
},
|
||||
|
||||
// TODO: any -> Partial<Cypress.Loggable & Cypress.Timeoutable>
|
||||
root (options: any = {}) {
|
||||
const userOptions = options
|
||||
|
||||
options = _.defaults({}, userOptions, { log: true })
|
||||
|
||||
if (options.log !== false) {
|
||||
options._log = Cypress.log({
|
||||
message: '',
|
||||
timeout: options.timeout,
|
||||
})
|
||||
}
|
||||
|
||||
const log = ($el) => {
|
||||
if (options.log) {
|
||||
options._log.set({ $el })
|
||||
}
|
||||
|
||||
return $el
|
||||
}
|
||||
|
||||
const withinSubject = state('withinSubject')
|
||||
|
||||
if (withinSubject) {
|
||||
return log(withinSubject)
|
||||
}
|
||||
|
||||
return cy.now('get', 'html', { log: false }).then(log)
|
||||
},
|
||||
})
|
||||
|
||||
Commands.addAll({ prevSubject: ['optional', 'window', 'document', 'element'] }, {
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import _ from 'lodash'
|
||||
|
||||
export default (Commands, Cypress, cy, state) => {
|
||||
Commands.addAll({
|
||||
// TODO: any -> Partial<Cypress.Loggable & Cypress.Timeoutable>
|
||||
root (options: any = {}) {
|
||||
const userOptions = options
|
||||
|
||||
options = _.defaults({}, userOptions, { log: true })
|
||||
|
||||
if (options.log !== false) {
|
||||
options._log = Cypress.log({
|
||||
message: '',
|
||||
timeout: options.timeout,
|
||||
})
|
||||
}
|
||||
|
||||
const log = ($el) => {
|
||||
if (options.log) {
|
||||
options._log.set({ $el })
|
||||
}
|
||||
|
||||
return $el
|
||||
}
|
||||
|
||||
const withinSubject = state('withinSubject')
|
||||
|
||||
if (withinSubject) {
|
||||
return log(withinSubject)
|
||||
}
|
||||
|
||||
return cy.now('get', 'html', { log: false }).then(log)
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -148,23 +148,30 @@ class $Cypress {
|
||||
this.config = $SetterGetter.create(config, (config) => {
|
||||
if (!window.top.__cySkipValidateConfig) {
|
||||
validateNoReadOnlyConfig(config, (errProperty) => {
|
||||
let errMessage
|
||||
const errPath = this.state('runnable')
|
||||
? 'config.invalid_cypress_config_override'
|
||||
: 'config.invalid_test_config_override'
|
||||
|
||||
if (this.state('runnable')) {
|
||||
errMessage = $errUtils.errByPath('config.invalid_cypress_config_override', {
|
||||
errProperty,
|
||||
})
|
||||
} else {
|
||||
errMessage = $errUtils.errByPath('config.invalid_test_config_override', {
|
||||
errProperty,
|
||||
})
|
||||
}
|
||||
const errMsg = $errUtils.errByPath(errPath, {
|
||||
errProperty,
|
||||
})
|
||||
|
||||
throw new this.state('specWindow').Error(errMessage)
|
||||
throw new this.state('specWindow').Error(errMsg)
|
||||
})
|
||||
}
|
||||
|
||||
validate(config, (errMsg) => {
|
||||
validate(config, (errResult) => {
|
||||
const stringify = (str) => format(JSON.stringify(str))
|
||||
|
||||
const format = (str) => `\`${str}\``
|
||||
|
||||
// TODO: this does not use the @packages/error rewriting rules
|
||||
// for stdout vs markdown - it always inserts backticks for markdown
|
||||
// and those leak out into the stdout formatting.
|
||||
const errMsg = _.isString(errResult)
|
||||
? errResult
|
||||
: `Expected ${format(errResult.key)} to be ${errResult.type}.\n\nInstead the value was: ${stringify(errResult.value)}\``
|
||||
|
||||
throw new this.state('specWindow').Error(errMsg)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// @ts-nocheck
|
||||
import _ from 'lodash'
|
||||
import $utils from './utils'
|
||||
import $errUtils from './error_utils'
|
||||
@@ -36,12 +35,16 @@ const _isBrowser = (browser, matcher, errPrefix) => {
|
||||
}
|
||||
}
|
||||
|
||||
const isBrowser = (config, obj = '', errPrefix = '`Cypress.isBrowser()`') => {
|
||||
// TODO: change the type of `any` to `IsBrowserMatcher`
|
||||
const isBrowser = (config, obj: any = '', errPrefix: string = '`Cypress.isBrowser()`') => {
|
||||
return _
|
||||
.chain(obj)
|
||||
.concat([])
|
||||
.map((matcher) => _isBrowser(config.browser, matcher, errPrefix))
|
||||
.reduce((a, b) => {
|
||||
.reduce((
|
||||
a: null | { isMatch: boolean, exclusive: boolean },
|
||||
b: { isMatch: boolean, exclusive: boolean },
|
||||
) => {
|
||||
if (!a) return b
|
||||
|
||||
if (a.exclusive && b.exclusive) {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// @ts-nocheck
|
||||
import _ from 'lodash'
|
||||
import $ from 'jquery'
|
||||
import $dom from '../dom'
|
||||
@@ -33,7 +32,12 @@ const maybeCastNumberToString = (num) => {
|
||||
return _.isFinite(num) ? `${num}` : num
|
||||
}
|
||||
|
||||
export const $chaiJquery = (chai, chaiUtils, callbacks = {}) => {
|
||||
interface Callbacks {
|
||||
onInvalid: (method, obj) => void
|
||||
onError: (err, method, obj, negated) => void
|
||||
}
|
||||
|
||||
export const $chaiJquery = (chai, chaiUtils, callbacks: Callbacks) => {
|
||||
const { inspect, flag } = chaiUtils
|
||||
|
||||
const assertDom = (ctx, method, ...args) => {
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import _ from 'lodash'
|
||||
|
||||
import $errUtils from './error_utils'
|
||||
import $stackUtils from './stack_utils'
|
||||
|
||||
import { allCommands } from '../cy/commands'
|
||||
import { addCommand as addNetstubbingCommand } from '../cy/net-stubbing'
|
||||
import { addCommands as addMultiDomainCommands } from '../cy/multi-domain'
|
||||
import $errUtils from './error_utils'
|
||||
import $stackUtils from './stack_utils'
|
||||
|
||||
const builtInCommands = [
|
||||
// `default` is necessary if a file uses `export default` syntax.
|
||||
// @ts-ignore
|
||||
..._.toArray(allCommands).map((c) => c.default || c),
|
||||
addNetstubbingCommand,
|
||||
addMultiDomainCommands,
|
||||
@@ -76,7 +74,7 @@ export default {
|
||||
const overridden = _.clone(original)
|
||||
|
||||
overridden.fn = function (...args) {
|
||||
args = [].concat(originalFn, args)
|
||||
args = ([] as any).concat(originalFn, args)
|
||||
|
||||
return fn.apply(this, args)
|
||||
}
|
||||
@@ -142,7 +140,7 @@ export default {
|
||||
errProps: {
|
||||
appendToStack: {
|
||||
title: 'From Cypress Internals',
|
||||
content: $stackUtils.stackWithoutMessage((new Error('add command internal stack')).stack),
|
||||
content: $stackUtils.stackWithoutMessage((new Error('add command internal stack')).stack || ''),
|
||||
} },
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import _ from 'lodash'
|
||||
import Cookies from 'js-cookie'
|
||||
|
||||
@@ -10,13 +8,13 @@ let isDebuggingVerbose = false
|
||||
|
||||
const preserved = {}
|
||||
|
||||
const defaults = {
|
||||
const defaults: any = {
|
||||
preserve: null,
|
||||
}
|
||||
|
||||
const warnOnWhitelistRenamed = (obj, type) => {
|
||||
if (obj.whitelist) {
|
||||
return $errUtils.throwErrByPath('cookies.whitelist_renamed', { args: { type } })
|
||||
$errUtils.throwErrByPath('cookies.whitelist_renamed', { args: { type } })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,10 +51,12 @@ export const $Cookies = (namespace, domain) => {
|
||||
if (preserved[name]) {
|
||||
return delete preserved[name]
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
const API = {
|
||||
debug (bool = true, options = {}) {
|
||||
debug (bool = true, options: any = {}) {
|
||||
_.defaults(options, {
|
||||
verbose: true,
|
||||
})
|
||||
@@ -82,7 +82,7 @@ export const $Cookies = (namespace, domain) => {
|
||||
return console[m].apply(console, args)
|
||||
},
|
||||
|
||||
getClearableCookies (cookies = []) {
|
||||
getClearableCookies (cookies: any[] = []) {
|
||||
return _.filter(cookies, (cookie) => {
|
||||
return !isAllowed(cookie) && !removePreserved(cookie.name)
|
||||
})
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
// @ts-nocheck
|
||||
|
||||
// See: ./errorScenarios.md for details about error messages and stack traces
|
||||
|
||||
import _ from 'lodash'
|
||||
import chai from 'chai'
|
||||
|
||||
import _ from 'lodash'
|
||||
import $dom from '../dom'
|
||||
import $utils from './utils'
|
||||
import $stackUtils from './stack_utils'
|
||||
import $errorMessages from './error_messages'
|
||||
import $stackUtils, { StackAndCodeFrameIndex } from './stack_utils'
|
||||
import $utils from './utils'
|
||||
|
||||
const ERROR_PROPS = 'message type name stack sourceMappedStack parsedStack fileName lineNumber columnNumber host uncaught actual expected showDiff isPending docsUrl codeFrame'.split(' ')
|
||||
const ERR_PREPARED_FOR_SERIALIZATION = Symbol('ERR_PREPARED_FOR_SERIALIZATION')
|
||||
@@ -17,9 +14,9 @@ const crossOriginScriptRe = /^script error/i
|
||||
|
||||
if (!Error.captureStackTrace) {
|
||||
Error.captureStackTrace = (err, fn) => {
|
||||
const stack = (new Error()).stack
|
||||
const stack = (new Error()).stack;
|
||||
|
||||
err.stack = $stackUtils.stackWithLinesDroppedFromMarker(stack, fn.name)
|
||||
(err as Error).stack = $stackUtils.stackWithLinesDroppedFromMarker(stack, fn?.name)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,15 +60,15 @@ const wrapErr = (err) => {
|
||||
return $utils.reduceProps(err, ERROR_PROPS)
|
||||
}
|
||||
|
||||
const isAssertionErr = (err = {}) => {
|
||||
const isAssertionErr = (err: Error) => {
|
||||
return err.name === 'AssertionError'
|
||||
}
|
||||
|
||||
const isChaiValidationErr = (err = {}) => {
|
||||
const isChaiValidationErr = (err: Error) => {
|
||||
return _.startsWith(err.message, 'Invalid Chai property')
|
||||
}
|
||||
|
||||
const isCypressErr = (err = {}) => {
|
||||
const isCypressErr = (err: Error): boolean => {
|
||||
return err.name === 'CypressError'
|
||||
}
|
||||
|
||||
@@ -79,7 +76,7 @@ const isSpecError = (spec, err) => {
|
||||
return _.includes(err.stack, spec.relative)
|
||||
}
|
||||
|
||||
const mergeErrProps = (origErr: Error, ...newProps) => {
|
||||
const mergeErrProps = (origErr: Error, ...newProps): Error => {
|
||||
return _.extend(origErr, ...newProps)
|
||||
}
|
||||
|
||||
@@ -197,7 +194,7 @@ const makeErrFromObj = (obj) => {
|
||||
return err2
|
||||
}
|
||||
|
||||
const throwErr = (err, options = {}) => {
|
||||
const makeErrFromErr = (err, options: any = {}) => {
|
||||
if (_.isString(err)) {
|
||||
err = cypressErr({ message: err })
|
||||
}
|
||||
@@ -205,12 +202,12 @@ const throwErr = (err, options = {}) => {
|
||||
let { onFail, errProps } = options
|
||||
|
||||
// assume onFail is a command if
|
||||
//# onFail is present and isn't a function
|
||||
// onFail is present and isn't a function
|
||||
if (onFail && !_.isFunction(onFail)) {
|
||||
const command = onFail
|
||||
|
||||
//# redefine onFail and automatically
|
||||
//# hook this into our command
|
||||
// redefine onFail and automatically
|
||||
// hook this into our command
|
||||
onFail = (err) => {
|
||||
return command.error(err)
|
||||
}
|
||||
@@ -224,10 +221,14 @@ const throwErr = (err, options = {}) => {
|
||||
_.extend(err, errProps)
|
||||
}
|
||||
|
||||
throw err
|
||||
return err
|
||||
}
|
||||
|
||||
const throwErrByPath = (errPath, options = {}) => {
|
||||
const throwErr = (err, options: any = {}): never => {
|
||||
throw makeErrFromErr(err, options)
|
||||
}
|
||||
|
||||
const throwErrByPath = (errPath, options: any = {}): never => {
|
||||
const err = errByPath(errPath, options.args)
|
||||
|
||||
if (options.stack) {
|
||||
@@ -237,15 +238,16 @@ const throwErrByPath = (errPath, options = {}) => {
|
||||
Error.captureStackTrace(err, throwErrByPath)
|
||||
}
|
||||
|
||||
throwErr(err, options)
|
||||
throw makeErrFromErr(err, options)
|
||||
}
|
||||
|
||||
const warnByPath = (errPath, options = {}) => {
|
||||
const warnByPath = (errPath, options: any = {}) => {
|
||||
const errObj = errByPath(errPath, options.args)
|
||||
let err = errObj.message
|
||||
const docsUrl = (errObj as CypressError).docsUrl
|
||||
|
||||
if (errObj.docsUrl) {
|
||||
err += `\n\n${errObj.docsUrl}`
|
||||
if (docsUrl) {
|
||||
err += `\n\n${docsUrl}`
|
||||
}
|
||||
|
||||
$utils.warning(err)
|
||||
@@ -266,6 +268,7 @@ export class InternalCypressError extends Error {
|
||||
export class CypressError extends Error {
|
||||
docsUrl?: string
|
||||
retry?: boolean
|
||||
userInvocationStack?: any
|
||||
|
||||
constructor (message) {
|
||||
super(message)
|
||||
@@ -297,10 +300,10 @@ const internalErr = (err): InternalCypressError => {
|
||||
const cypressErr = (err): CypressError => {
|
||||
const newErr = new CypressError(err.message)
|
||||
|
||||
return mergeErrProps(newErr, err)
|
||||
return mergeErrProps(newErr, err) as CypressError
|
||||
}
|
||||
|
||||
const cypressErrByPath = (errPath, options = {}) => {
|
||||
const cypressErrByPath = (errPath, options: any = {}) => {
|
||||
const errObj = errByPath(errPath, options.args)
|
||||
|
||||
return cypressErr(errObj)
|
||||
@@ -376,7 +379,7 @@ const createUncaughtException = ({ frameType, handlerType, state, err }) => {
|
||||
let uncaughtErr = errByPath(errPath, {
|
||||
errMsg: err.message,
|
||||
promiseAddendum: handlerType === 'unhandledrejection' ? ' It was caused by an unhandled promise rejection.' : '',
|
||||
})
|
||||
}) as CypressError
|
||||
|
||||
modifyErrMsg(err, uncaughtErr.message, () => uncaughtErr.message)
|
||||
|
||||
@@ -394,14 +397,14 @@ const createUncaughtException = ({ frameType, handlerType, state, err }) => {
|
||||
// stacks from command failures and assertion failures have the right message
|
||||
// but the stack points to cypress internals. here we replace the internal
|
||||
// cypress stack with the invocation stack, which points to the user's code
|
||||
const stackAndCodeFrameIndex = (err, userInvocationStack) => {
|
||||
const stackAndCodeFrameIndex = (err, userInvocationStack): StackAndCodeFrameIndex => {
|
||||
if (!userInvocationStack) return { stack: err.stack }
|
||||
|
||||
if (isCypressErr(err) || isChaiValidationErr(err)) {
|
||||
return $stackUtils.stackWithUserInvocationStackSpliced(err, userInvocationStack)
|
||||
}
|
||||
|
||||
return { stack: $stackUtils.replacedStack(err, userInvocationStack) }
|
||||
return { stack: $stackUtils.replacedStack(err, userInvocationStack) || '' }
|
||||
}
|
||||
|
||||
const preferredStackAndCodeFrameIndex = (err, userInvocationStack) => {
|
||||
@@ -427,7 +430,7 @@ const enhanceStack = ({ err, userInvocationStack, projectRoot }) => {
|
||||
|
||||
// all errors flow through this function before they're finally thrown
|
||||
// or used to reject promises
|
||||
const processErr = (errObj = {}, config) => {
|
||||
const processErr = (errObj: CypressError, config) => {
|
||||
let docsUrl = errObj.docsUrl
|
||||
|
||||
if (config('isInteractive') || !docsUrl) {
|
||||
@@ -482,7 +485,7 @@ const errorFromErrorEvent = (event): ErrorFromErrorEvent => {
|
||||
// reset the message on a cross origin script error
|
||||
// since no details are accessible
|
||||
if (crossOriginScriptRe.test(message)) {
|
||||
const crossOriginErr = errByPath('uncaught.cross_origin_script')
|
||||
const crossOriginErr = errByPath('uncaught.cross_origin_script') as CypressError
|
||||
|
||||
message = crossOriginErr.message
|
||||
docsUrl = crossOriginErr.docsUrl
|
||||
@@ -490,9 +493,9 @@ const errorFromErrorEvent = (event): ErrorFromErrorEvent => {
|
||||
|
||||
// it's possible the error was thrown as a string (throw 'some error')
|
||||
// so create it in the case it's not already an object
|
||||
const err = _.isObject(error) ? error : convertErrorEventPropertiesToObject({
|
||||
const err = (_.isObject(error) ? error : convertErrorEventPropertiesToObject({
|
||||
message, filename, lineno, colno,
|
||||
})
|
||||
})) as CypressError
|
||||
|
||||
err.docsUrl = docsUrl
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// @ts-nocheck
|
||||
// TODO:
|
||||
// 1. test these method implementations using encoded characters
|
||||
// look at the spec to figure out whether we SHOULD be decoding them
|
||||
@@ -18,6 +17,8 @@ const reLocalHost = /^(localhost|0\.0\.0\.0|127\.0\.0\.1)/
|
||||
const reQueryParam = /\?[^/]+/
|
||||
|
||||
export class $Location {
|
||||
remote: UrlParse
|
||||
|
||||
constructor (remote) {
|
||||
this.remote = new UrlParse(remote)
|
||||
}
|
||||
@@ -38,6 +39,8 @@ export class $Location {
|
||||
password,
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
getHash () {
|
||||
|
||||
@@ -7,7 +7,7 @@ import { codeFrameColumns } from '@babel/code-frame'
|
||||
|
||||
import $utils from './utils'
|
||||
import $sourceMapUtils from './source_map_utils'
|
||||
import { getStackLines, replacedStack, stackWithoutMessage, splitStack, unsplitStack } from '@packages/server/lib/util/stack_utils'
|
||||
import { getStackLines, replacedStack, stackWithoutMessage, splitStack, unsplitStack } from '@packages/errors/src/stackUtils'
|
||||
|
||||
const whitespaceRegex = /^(\s*)*/
|
||||
const stackLineRegex = /^\s*(at )?.*@?\(?.*\:\d+\:\d+\)?$/
|
||||
@@ -66,7 +66,12 @@ const stackWithReplacementMarkerLineRemoved = (stack) => {
|
||||
})
|
||||
}
|
||||
|
||||
const stackWithUserInvocationStackSpliced = (err, userInvocationStack) => {
|
||||
export type StackAndCodeFrameIndex = {
|
||||
stack: string
|
||||
index?: number
|
||||
}
|
||||
|
||||
const stackWithUserInvocationStackSpliced = (err, userInvocationStack): StackAndCodeFrameIndex => {
|
||||
const stack = _.trim(err.stack, '\n') // trim newlines from end
|
||||
const [messageLines, stackLines] = splitStack(stack)
|
||||
const userInvocationStackWithoutMessage = stackWithoutMessage(userInvocationStack)
|
||||
@@ -139,13 +144,21 @@ const captureUserInvocationStack = (ErrorConstructor, userInvocationStack?) => {
|
||||
if (!userInvocationStack) {
|
||||
const newErr = new ErrorConstructor('userInvocationStack')
|
||||
|
||||
userInvocationStack = newErr.stack
|
||||
|
||||
// if browser natively supports Error.captureStackTrace, use it (chrome) (must be bound)
|
||||
// otherwise use our polyfill on top.Error
|
||||
const captureStackTrace = ErrorConstructor.captureStackTrace ? ErrorConstructor.captureStackTrace.bind(ErrorConstructor) : Error.captureStackTrace
|
||||
|
||||
captureStackTrace(newErr, captureUserInvocationStack)
|
||||
|
||||
userInvocationStack = newErr.stack
|
||||
// On Chrome 99+, captureStackTrace strips away the whole stack,
|
||||
// leaving nothing beyond the error message. If we get back a single line
|
||||
// (just the error message with no stack trace), then use the original value
|
||||
// instead of the trimmed one.
|
||||
if (newErr.stack.match('\n')) {
|
||||
userInvocationStack = newErr.stack
|
||||
}
|
||||
}
|
||||
|
||||
userInvocationStack = normalizedUserInvocationStack(userInvocationStack)
|
||||
|
||||
@@ -98,7 +98,7 @@ export default {
|
||||
throw new Error(`The switch/case value: '${value}' did not match any cases: ${keys.join(', ')}.`)
|
||||
},
|
||||
|
||||
reduceProps (obj, props = []) {
|
||||
reduceProps (obj, props: string[] = []) {
|
||||
if (!obj) {
|
||||
return null
|
||||
}
|
||||
@@ -355,7 +355,7 @@ export default {
|
||||
|
||||
// normalize more than {maxNewLines} new lines into
|
||||
// exactly {replacementNumLines} new lines
|
||||
normalizeNewLines (str, maxNewLines, replacementNumLines) {
|
||||
normalizeNewLines (str, maxNewLines, replacementNumLines?) {
|
||||
const moreThanMaxNewLinesRe = new RegExp(`\\n{${maxNewLines},}`)
|
||||
const replacementWithNumLines = replacementNumLines ?? maxNewLines
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ module.exports = {
|
||||
debug('dest path %s', dest)
|
||||
|
||||
// make sure this path exists!
|
||||
return fs.statAsync(appPath)
|
||||
return fs.accessAsync(appPath)
|
||||
.then(() => {
|
||||
debug('appPath exists %s', appPath)
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
## @packages/errors
|
||||
|
||||
Error definitions and utilities for Cypress
|
||||
|
||||
See [Error Handling Guide](../../guides/error-handling.md) for more info
|
||||
@@ -0,0 +1,38 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
|
||||
body {
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
padding: 0 1em;
|
||||
line-height: 1.4;
|
||||
color: #eee;
|
||||
background-color: #111;
|
||||
}
|
||||
pre {
|
||||
padding: 0 0;
|
||||
margin: 0 0;
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 5px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body><pre><span style="color:#e05561">Check your browser to continue logging in.<span style="color:#e6e6e6"></span></span>
|
||||
</pre></body></html>
|
||||
@@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
|
||||
body {
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
padding: 0 1em;
|
||||
line-height: 1.4;
|
||||
color: #eee;
|
||||
background-color: #111;
|
||||
}
|
||||
pre {
|
||||
padding: 0 0;
|
||||
margin: 0 0;
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 5px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body><pre><span style="color:#e05561">Cypress was unable to open your installed browser. To continue logging in, please open this URL in your web browser:<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4ec4ff">https://dashboard.cypress.io/login<span style="color:#e05561"><span style="color:#e6e6e6"></span></span></span></span></span></span></span></span>
|
||||
</pre></body></html>
|
||||
@@ -0,0 +1,38 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
|
||||
body {
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
padding: 0 1em;
|
||||
line-height: 1.4;
|
||||
color: #eee;
|
||||
background-color: #111;
|
||||
}
|
||||
pre {
|
||||
padding: 0 0;
|
||||
margin: 0 0;
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 5px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body><pre><span style="color:#e05561">The automation client disconnected. Cannot continue running tests.<span style="color:#e6e6e6"></span></span>
|
||||
</pre></body></html>
|
||||
@@ -0,0 +1,45 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
|
||||
body {
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
padding: 0 1em;
|
||||
line-height: 1.4;
|
||||
color: #eee;
|
||||
background-color: #111;
|
||||
}
|
||||
pre {
|
||||
padding: 0 0;
|
||||
margin: 0 0;
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 5px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body><pre><span style="color:#e05561">Cypress detected policy settings on your computer that may cause issues.<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">The following policies were detected that may prevent Cypress from automating Chrome:<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\ProxyServer<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">HKEY_CURRENT_USER\Software\Policies\Google\Chromium\ExtensionSettings<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">For more information, see https://on.cypress.io/bad-browser-policy<span style="color:#e6e6e6"></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>
|
||||
</pre></body></html>
|
||||
@@ -0,0 +1,38 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
|
||||
body {
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
padding: 0 1em;
|
||||
line-height: 1.4;
|
||||
color: #eee;
|
||||
background-color: #111;
|
||||
}
|
||||
pre {
|
||||
padding: 0 0;
|
||||
margin: 0 0;
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 5px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body><pre><span style="color:#e05561">Cypress detected policy settings on your computer that may cause issues with using this browser. For more information, see https://on.cypress.io/bad-browser-policy<span style="color:#e6e6e6"></span></span>
|
||||
</pre></body></html>
|
||||
@@ -0,0 +1,67 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
|
||||
body {
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
padding: 0 1em;
|
||||
line-height: 1.4;
|
||||
color: #eee;
|
||||
background-color: #111;
|
||||
}
|
||||
pre {
|
||||
padding: 0 0;
|
||||
margin: 0 0;
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 5px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body><pre><span style="color:#e05561">Can't run because you've entered an invalid browser name.<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">Browser: <span style="color:#e5e510">canary<span style="color:#e05561"> was not found on your system or is not supported by Cypress.<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">Cypress supports the following browsers:<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">electron<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">chrome<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">chromium<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">chrome:canary<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">edge<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">firefox<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">You can also use a custom browser: https://on.cypress.io/customize-browsers<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">Available browsers found on your system are:<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">chrome<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">chromium<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">chrome:beta<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">chrome:canary<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">firefox<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">firefox:dev<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">firefox:nightly<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">edge<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">edge:canary<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">edge:beta<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">edge:dev<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">Note: In Cypress version 4.0.0, Canary must be launched as <span style="color:#de73ff">chrome:canary<span style="color:#e05561">, not <span style="color:#de73ff">canary<span style="color:#e05561">.<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">See https://on.cypress.io/migration-guide for more information on breaking changes in 4.0.0.<span style="color:#e6e6e6"></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>
|
||||
</pre></body></html>
|
||||
@@ -0,0 +1,63 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
|
||||
body {
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
padding: 0 1em;
|
||||
line-height: 1.4;
|
||||
color: #eee;
|
||||
background-color: #111;
|
||||
}
|
||||
pre {
|
||||
padding: 0 0;
|
||||
margin: 0 0;
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 5px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body><pre><span style="color:#e05561">Can't run because you've entered an invalid browser name.<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">Browser: <span style="color:#e5e510">invalid-browser<span style="color:#e05561"> was not found on your system or is not supported by Cypress.<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">Cypress supports the following browsers:<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">electron<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">chrome<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">chromium<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">chrome:canary<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">edge<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">firefox<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">You can also use a custom browser: https://on.cypress.io/customize-browsers<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">Available browsers found on your system are:<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">chrome<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">chromium<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">chrome:beta<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">chrome:canary<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">firefox<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">firefox:dev<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">firefox:nightly<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">edge<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">edge:canary<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">edge:beta<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> - <span style="color:#e05561"><span style="color:#4ec4ff">edge:dev<span style="color:#e05561"><span style="color:#e6e6e6"></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>
|
||||
</pre></body></html>
|
||||
@@ -0,0 +1,42 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
|
||||
body {
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
padding: 0 1em;
|
||||
line-height: 1.4;
|
||||
color: #eee;
|
||||
background-color: #111;
|
||||
}
|
||||
pre {
|
||||
padding: 0 0;
|
||||
margin: 0 0;
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 5px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body><pre><span style="color:#e05561">We could not identify a known browser at the path you provided: <span style="color:#4ec4ff">/path/does/not/exist<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">The output from the command we ran was:<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#de73ff">fail whale<span style="color:#e05561"><span style="color:#e6e6e6"></span></span></span></span></span></span></span></span></span></span></span></span></span></span>
|
||||
</pre></body></html>
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
|
||||
body {
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
padding: 0 1em;
|
||||
line-height: 1.4;
|
||||
color: #eee;
|
||||
background-color: #111;
|
||||
}
|
||||
pre {
|
||||
padding: 0 0;
|
||||
margin: 0 0;
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 5px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body><pre><span style="color:#e05561">Oops...we found an error preparing this test file:<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> > <span style="color:#e05561"><span style="color:#4ec4ff">/path/to/file<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">The error was:<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e5e510">fail whale<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">This occurred while Cypress was compiling and bundling your test code. This is usually caused by:<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">- A missing file or dependency<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">- A syntax error in the file or one of its dependencies<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">Fix the error in your code and re-run your tests.<span style="color:#e6e6e6"></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>
|
||||
</pre></body></html>
|
||||
@@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
|
||||
body {
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
padding: 0 1em;
|
||||
line-height: 1.4;
|
||||
color: #eee;
|
||||
background-color: #111;
|
||||
}
|
||||
pre {
|
||||
padding: 0 0;
|
||||
margin: 0 0;
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 5px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body><pre><span style="color:#e05561">Cypress failed to verify that your server is running.<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">Please start this server and then run Cypress again.<span style="color:#e6e6e6"></span></span></span></span></span></span>
|
||||
</pre></body></html>
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
|
||||
body {
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
padding: 0 1em;
|
||||
line-height: 1.4;
|
||||
color: #eee;
|
||||
background-color: #111;
|
||||
}
|
||||
pre {
|
||||
padding: 0 0;
|
||||
margin: 0 0;
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 5px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body><pre><span style="color:#e05561"><span style="color:#4f5666">We will try connecting to it 60 more times...<span style="color:#e05561"><span style="color:#e6e6e6"></span></span></span></span>
|
||||
</pre></body></html>
|
||||
@@ -0,0 +1,46 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
|
||||
body {
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
padding: 0 1em;
|
||||
line-height: 1.4;
|
||||
color: #eee;
|
||||
background-color: #111;
|
||||
}
|
||||
pre {
|
||||
padding: 0 0;
|
||||
margin: 0 0;
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 5px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body><pre><span style="color:#e05561">Cypress could not verify that this server is running:<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> > <span style="color:#e05561"><span style="color:#4ec4ff">http://localhost:3000<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">We are verifying this server because it has been configured as your <span style="color:#e5e510">baseUrl<span style="color:#e05561">.<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">Cypress automatically waits until your server is accessible before running tests.<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666">We will try connecting to it 60 more times...<span style="color:#e05561"><span style="color:#e6e6e6"></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>
|
||||
</pre></body></html>
|
||||
@@ -0,0 +1,42 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
|
||||
body {
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
padding: 0 1em;
|
||||
line-height: 1.4;
|
||||
color: #eee;
|
||||
background-color: #111;
|
||||
}
|
||||
pre {
|
||||
padding: 0 0;
|
||||
margin: 0 0;
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 5px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body><pre><span style="color:#e05561">Cypress could not verify that this server is running:<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> > <span style="color:#e05561"><span style="color:#4ec4ff">http://localhost:3000<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">This server has been configured as your <span style="color:#e5e510">baseUrl<span style="color:#e05561">, and tests will likely fail if it is not running.<span style="color:#e6e6e6"></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>
|
||||
</pre></body></html>
|
||||
@@ -0,0 +1,38 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
|
||||
body {
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
padding: 0 1em;
|
||||
line-height: 1.4;
|
||||
color: #eee;
|
||||
background-color: #111;
|
||||
}
|
||||
pre {
|
||||
padding: 0 0;
|
||||
margin: 0 0;
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 5px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body><pre><span style="color:#e05561">Can't create project's secret key.<span style="color:#e6e6e6"></span></span>
|
||||
</pre></body></html>
|
||||
@@ -0,0 +1,38 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
|
||||
body {
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
padding: 0 1em;
|
||||
line-height: 1.4;
|
||||
color: #eee;
|
||||
background-color: #111;
|
||||
}
|
||||
pre {
|
||||
padding: 0 0;
|
||||
margin: 0 0;
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 5px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body><pre><span style="color:#e05561">Can't find project's secret key.<span style="color:#e6e6e6"></span></span>
|
||||
</pre></body></html>
|
||||
@@ -0,0 +1,48 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
|
||||
body {
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
padding: 0 1em;
|
||||
line-height: 1.4;
|
||||
color: #eee;
|
||||
background-color: #111;
|
||||
}
|
||||
pre {
|
||||
padding: 0 0;
|
||||
margin: 0 0;
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 5px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body><pre><span style="color:#e05561">You passed the <span style="color:#de73ff">--record<span style="color:#e05561"> flag but this project has not been setup to record.<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">This project is missing the <span style="color:#e5e510">projectId<span style="color:#e05561"> inside of: <span style="color:#4ec4ff">/path/to/cypress.json<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">We cannot uniquely identify this project without this id.<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">You need to setup this project to record. This will generate a unique projectId.<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">Alternatively if you omit the <span style="color:#de73ff">--record<span style="color:#e05561"> flag this project will run without recording.<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">https://on.cypress.io/recording-project-runs<span style="color:#e6e6e6"></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>
|
||||
</pre></body></html>
|
||||
@@ -0,0 +1,44 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
|
||||
body {
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
padding: 0 1em;
|
||||
line-height: 1.4;
|
||||
color: #eee;
|
||||
background-color: #111;
|
||||
}
|
||||
pre {
|
||||
padding: 0 0;
|
||||
margin: 0 0;
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 5px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body><pre><span style="color:#e05561">Warning: We failed to remove old browser profiles from previous runs.<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">This error will not alter the exit code.<span style="color:#e6e6e6">
|
||||
<span style="color:#c062de"><span style="color:#e6e6e6">
|
||||
<span style="color:#c062de">Error: fail whale<span style="color:#e6e6e6">
|
||||
<span style="color:#c062de"> at makeErr (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)<span style="color:#e6e6e6">
|
||||
<span style="color:#c062de"> at CANNOT_REMOVE_OLD_BROWSER_PROFILES (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)<span style="color:#e6e6e6"></span></span></span></span></span></span></span></span></span></span></span></span></span></span>
|
||||
</pre></body></html>
|
||||
@@ -0,0 +1,44 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
|
||||
body {
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
padding: 0 1em;
|
||||
line-height: 1.4;
|
||||
color: #eee;
|
||||
background-color: #111;
|
||||
}
|
||||
pre {
|
||||
padding: 0 0;
|
||||
margin: 0 0;
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 5px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body><pre><span style="color:#e05561">Warning: We failed to trash the existing run results.<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">This error will not alter the exit code.<span style="color:#e6e6e6">
|
||||
<span style="color:#c062de"><span style="color:#e6e6e6">
|
||||
<span style="color:#c062de">Error: fail whale<span style="color:#e6e6e6">
|
||||
<span style="color:#c062de"> at makeErr (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)<span style="color:#e6e6e6">
|
||||
<span style="color:#c062de"> at CANNOT_TRASH_ASSETS (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)<span style="color:#e6e6e6"></span></span></span></span></span></span></span></span></span></span></span></span></span></span>
|
||||
</pre></body></html>
|
||||
@@ -0,0 +1,46 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
|
||||
body {
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
padding: 0 1em;
|
||||
line-height: 1.4;
|
||||
color: #eee;
|
||||
background-color: #111;
|
||||
}
|
||||
pre {
|
||||
padding: 0 0;
|
||||
margin: 0 0;
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 5px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body><pre><span style="color:#e05561">Cypress failed to make a connection to the Chrome DevTools Protocol after retrying for 50 seconds.<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">This usually indicates there was a problem opening the Chrome browser.<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">The CDP port requested was <span style="color:#e5e510">2345<span style="color:#e05561">.<span style="color:#e6e6e6">
|
||||
<span style="color:#c062de"><span style="color:#e6e6e6">
|
||||
<span style="color:#c062de">Error: fail whale<span style="color:#e6e6e6">
|
||||
<span style="color:#c062de"> at makeErr (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)<span style="color:#e6e6e6">
|
||||
<span style="color:#c062de"> at CDP_COULD_NOT_CONNECT (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)<span style="color:#e6e6e6"></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>
|
||||
</pre></body></html>
|
||||
@@ -0,0 +1,42 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
|
||||
body {
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
padding: 0 1em;
|
||||
line-height: 1.4;
|
||||
color: #eee;
|
||||
background-color: #111;
|
||||
}
|
||||
pre {
|
||||
padding: 0 0;
|
||||
margin: 0 0;
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 5px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body><pre><span style="color:#e05561">There was an error reconnecting to the Chrome DevTools protocol. Please restart the browser.<span style="color:#e6e6e6">
|
||||
<span style="color:#c062de"><span style="color:#e6e6e6">
|
||||
<span style="color:#c062de">Error: fail whale<span style="color:#e6e6e6">
|
||||
<span style="color:#c062de"> at makeErr (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)<span style="color:#e6e6e6">
|
||||
<span style="color:#c062de"> at CDP_COULD_NOT_RECONNECT (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)<span style="color:#e6e6e6"></span></span></span></span></span></span></span></span></span></span>
|
||||
</pre></body></html>
|
||||
@@ -0,0 +1,38 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
|
||||
body {
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
padding: 0 1em;
|
||||
line-height: 1.4;
|
||||
color: #eee;
|
||||
background-color: #111;
|
||||
}
|
||||
pre {
|
||||
padding: 0 0;
|
||||
margin: 0 0;
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 5px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body><pre><span style="color:#e05561">Still waiting to connect to Chrome, retrying in 1 second <span style="color:#4f5666">(attempt 1/62)<span style="color:#e05561"><span style="color:#e6e6e6"></span></span></span></span>
|
||||
</pre></body></html>
|
||||
@@ -0,0 +1,38 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
|
||||
body {
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
padding: 0 1em;
|
||||
line-height: 1.4;
|
||||
color: #eee;
|
||||
background-color: #111;
|
||||
}
|
||||
pre {
|
||||
padding: 0 0;
|
||||
margin: 0 0;
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 5px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body><pre><span style="color:#e05561">A minimum CDP version of <span style="color:#e5e510">1.3<span style="color:#e05561"> is required, but the current browser has an older version.<span style="color:#e6e6e6"></span></span></span></span>
|
||||
</pre></body></html>
|
||||
@@ -0,0 +1,38 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
|
||||
body {
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
padding: 0 1em;
|
||||
line-height: 1.4;
|
||||
color: #eee;
|
||||
background-color: #111;
|
||||
}
|
||||
pre {
|
||||
padding: 0 0;
|
||||
margin: 0 0;
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 5px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body><pre><span style="color:#e05561">A minimum CDP version of <span style="color:#e5e510">1.3<span style="color:#e05561"> is required, but the current browser has <span style="color:#e5e510">1.2<span style="color:#e05561">.<span style="color:#e6e6e6"></span></span></span></span></span></span>
|
||||
</pre></body></html>
|
||||
@@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
|
||||
body {
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
padding: 0 1em;
|
||||
line-height: 1.4;
|
||||
color: #eee;
|
||||
background-color: #111;
|
||||
}
|
||||
pre {
|
||||
padding: 0 0;
|
||||
margin: 0 0;
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 5px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body><pre><span style="color:#e05561">Your project has set the configuration option: <span style="color:#e5e510">chromeWebSecurity<span style="color:#e05561"> to <span style="color:#4ec4ff">false<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">This option will not have an effect in Firefox. Tests that rely on web security being disabled will not run as expected.<span style="color:#e6e6e6"></span></span></span></span></span></span></span></span></span></span>
|
||||
</pre></body></html>
|
||||
@@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
|
||||
body {
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
padding: 0 1em;
|
||||
line-height: 1.4;
|
||||
color: #eee;
|
||||
background-color: #111;
|
||||
}
|
||||
pre {
|
||||
padding: 0 0;
|
||||
margin: 0 0;
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 5px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body><pre><span style="color:#e05561">There is both a <span style="color:#e5e510">cypress.config.js<span style="color:#e05561"> and a <span style="color:#e5e510">cypress.config.ts<span style="color:#e05561"> at the location below:<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#4f5666"> > <span style="color:#e05561"><span style="color:#4ec4ff">/path/to/project/root<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">Cypress does not know which one to read for config. Please remove one of the two and try again.<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6"></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>
|
||||
</pre></body></html>
|
||||
@@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
|
||||
body {
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
padding: 0 1em;
|
||||
line-height: 1.4;
|
||||
color: #eee;
|
||||
background-color: #111;
|
||||
}
|
||||
pre {
|
||||
padding: 0 0;
|
||||
margin: 0 0;
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 5px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body><pre><span style="color:#e05561">Could not find a Cypress configuration file.<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">We looked but did not find a <span style="color:#e5e510">cypress.json<span style="color:#e05561"> file in this folder: <span style="color:#4ec4ff">/path/to/project/root<span style="color:#e05561"><span style="color:#e6e6e6"></span></span></span></span></span></span></span></span></span></span>
|
||||
</pre></body></html>
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
|
||||
body {
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
padding: 0 1em;
|
||||
line-height: 1.4;
|
||||
color: #eee;
|
||||
background-color: #111;
|
||||
}
|
||||
pre {
|
||||
padding: 0 0;
|
||||
margin: 0 0;
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 5px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body><pre><span style="color:#e05561">Your <span style="color:#e5e510">configFile<span style="color:#e05561"> set an invalid value from: <span style="color:#4ec4ff">cypress.json<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">Expected <span style="color:#e5e510">defaultCommandTimeout<span style="color:#e05561"> to be a number.<span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561">Instead the value was: <span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#de73ff">[<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#de73ff"> 1,<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#de73ff"> 2,<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#de73ff"> 3<span style="color:#e05561"><span style="color:#e6e6e6">
|
||||
<span style="color:#e05561"><span style="color:#de73ff">]<span style="color:#e05561"><span style="color:#e6e6e6"></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>
|
||||
</pre></body></html>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user