Skip to content

Commit 7aac450

Browse files
committed
Merge branch 'develop'
2 parents 2c6cd9e + 02e769f commit 7aac450

File tree

235 files changed

+1393
-943
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

235 files changed

+1393
-943
lines changed

.husky/pre-commit

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/sh
2+
. "$(dirname "$0")/_/husky.sh"
3+
4+
npx lint-staged

CONTRIBUTING.md

Lines changed: 63 additions & 57 deletions
Large diffs are not rendered by default.

browser-versions.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
2-
"chrome:beta": "94.0.4606.54",
3-
"chrome:stable": "94.0.4606.54"
2+
"chrome:beta": "95.0.4638.40",
3+
"chrome:stable": "94.0.4606.71"
44
}

circle.yml

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,20 @@ commands:
425425
steps:
426426
- restore_cached_workspace
427427
- run:
428-
command: yarn workspace @packages/server test ./test/e2e/$(( $CIRCLE_NODE_INDEX ))_*spec* --browser <<parameters.browser>>
428+
command: |
429+
ALL_SPECS=`circleci tests glob "/root/cypress/packages/server/test/e2e/*spec*"`
430+
SPECS=
431+
for file in $ALL_SPECS; do
432+
# filter out non_root tests, they have their own stage
433+
if [[ "$file" == *"non_root"* ]]; then
434+
echo "Skipping $file"
435+
continue
436+
fi
437+
SPECS="$SPECS $file"
438+
done
439+
SPECS=`echo $SPECS | xargs -n 1 | circleci tests split --split-by=timings`
440+
echo SPECS=$SPECS
441+
yarn workspace @packages/server test $SPECS --browser <<parameters.browser>>
429442
- verify-mocha-results
430443
- store_test_results:
431444
path: /tmp/cypress

cli/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ yarn test-watch --scope cypress
2929
yarn test-debug --scope cypress
3030
```
3131

32-
### Updating snaphots
32+
### Updating snapshots
3333

3434
Prepend `SNAPSHOT_UPDATE=1` to any test command. See [`snap-shot-it` instructions](https://github.com/bahmutov/snap-shot-it#advanced-use) for more info.
3535

cli/lib/cypress.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,23 @@ const cypressModuleApi = {
6868
return cli.parseRunCommand(args)
6969
},
7070
},
71+
72+
/**
73+
* Provides automatic code completion for configuration in many popular code editors.
74+
* While it's not strictly necessary for Cypress to parse your configuration, we
75+
* recommend wrapping your config object with `defineConfig()`
76+
* @example
77+
* module.exports = defineConfig({
78+
* viewportWith: 400
79+
* })
80+
*
81+
* @see ../types/cypress-npm-api.d.ts
82+
* @param {Cypress.ConfigOptions} config
83+
* @returns {Cypress.ConfigOptions} the configuration passed in parameter
84+
*/
85+
defineConfig (config) {
86+
return config
87+
},
7188
}
7289

7390
module.exports = cypressModuleApi

cli/types/cypress-npm-api.d.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,21 @@ declare module 'cypress' {
377377
* Cypress does
378378
*/
379379
cli: CypressCommandLine.CypressCliParser
380+
381+
/**
382+
* Provides automatic code completion for configuration in many popular code editors.
383+
* While it's not strictly necessary for Cypress to parse your configuration, we
384+
* recommend wrapping your config object with `defineConfig()`
385+
* @example
386+
* module.exports = defineConfig({
387+
* viewportWith: 400
388+
* })
389+
*
390+
* @see ../types/cypress-npm-api.d.ts
391+
* @param {Cypress.ConfigOptions} config
392+
* @returns {Cypress.ConfigOptions} the configuration passed in parameter
393+
*/
394+
defineConfig(config: Cypress.ConfigOptions): Cypress.ConfigOptions
380395
}
381396

382397
// export Cypress NPM module interface

cli/types/cypress.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2992,6 +2992,7 @@ declare namespace Cypress {
29922992
disableTimersAndAnimations: boolean
29932993
padding: Padding
29942994
scale: boolean
2995+
overwrite: boolean
29952996
onBeforeScreenshot: ($el: JQuery) => void
29962997
onAfterScreenshot: ($el: JQuery, props: {
29972998
path: string

package.json

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "cypress",
3-
"version": "8.5.0",
3+
"version": "8.6.0",
44
"description": "Cypress.io end to end testing tool",
55
"private": true,
66
"scripts": {
@@ -64,12 +64,8 @@
6464
"type-check": "node scripts/type_check",
6565
"verify:mocha:results": "node ./scripts/verify_mocha_results",
6666
"prewatch": "yarn ensure-deps",
67-
"watch": "lerna exec yarn watch --parallel --stream"
68-
},
69-
"husky": {
70-
"hooks": {
71-
"pre-commit": "lint-staged"
72-
}
67+
"watch": "lerna exec yarn watch --parallel --stream",
68+
"prepare": "husky install"
7369
},
7470
"devDependencies": {
7571
"@cypress/bumpercar": "2.0.12",
@@ -147,7 +143,7 @@
147143
"hasha": "5.0.0",
148144
"http-server": "0.12.3",
149145
"human-interval": "1.0.0",
150-
"husky": "2.4.1",
146+
"husky": "7.0.2",
151147
"inquirer": "3.3.0",
152148
"inquirer-confirm": "2.0.3",
153149
"jest": "24.9.0",
@@ -157,7 +153,7 @@
157153
"konfig": "0.2.1",
158154
"lazy-ass": "1.6.0",
159155
"lerna": "3.20.2",
160-
"lint-staged": "11.0.0",
156+
"lint-staged": "11.1.2",
161157
"listr2": "3.8.3",
162158
"lodash": "4.17.21",
163159
"make-empty-github-commit": "cypress-io/make-empty-github-commit#4a592aedb776ba2f4cc88979055315a53eec42ee",

packages/desktop-gui/cypress/integration/project_nav_spec.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -437,11 +437,17 @@ describe('Project Nav', function () {
437437
cy.get('.browsers .fa-exclamation-triangle').trigger('mouseover')
438438

439439
cy.get('.cy-tooltip').should('contain', 'Cypress detected policy settings on your computer that may cause issues with using this browser. For more information, see')
440-
cy.get('.cy-tooltip a').click().then(function () {
440+
441+
// prevent tooltips from being hidden so we can snapshot the state
442+
// of the browser warning tooltip
443+
cy.percySnapshot({ elementOverrides: [] })
444+
445+
cy
446+
.get('.cy-tooltip a')
447+
.click()
448+
.then(function () {
441449
expect(this.ipc.externalOpen).to.be.calledWith('https://on.cypress.io/bad-browser-policy')
442450
})
443-
444-
cy.percySnapshot()
445451
})
446452
})
447453

packages/desktop-gui/cypress/integration/settings_spec.js

Lines changed: 51 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -358,34 +358,52 @@ describe('Settings', () => {
358358
})
359359

360360
describe('project id panel', () => {
361-
beforeEach(function () {
362-
this.openProject.resolve(this.config)
363-
this.projectStatuses[0].id = this.config.projectId
364-
this.getProjectStatus.resolve(this.projectStatuses[0])
361+
context('with json file', () => {
362+
beforeEach(function () {
363+
this.openProject.resolve(this.config)
364+
this.projectStatuses[0].id = this.config.projectId
365+
this.getProjectStatus.resolve(this.projectStatuses[0])
365366

366-
this.goToSettings()
367-
cy.contains('Project ID').click()
368-
})
367+
this.goToSettings()
368+
cy.contains('Project ID').click()
369+
})
369370

370-
it('displays project id section', function () {
371-
cy.contains(this.config.projectId)
372-
cy.percySnapshot()
373-
})
371+
it('displays project id section', function () {
372+
cy.contains(this.config.projectId)
373+
cy.percySnapshot()
374+
})
375+
376+
it('shows tooltip on hover of copy to clipboard', () => {
377+
cy.get('.action-copy').trigger('mouseover')
378+
cy.get('.cy-tooltip').should('contain', 'Copy to clipboard')
379+
})
374380

375-
it('shows tooltip on hover of copy to clipboard', () => {
376-
cy.get('.action-copy').trigger('mouseover')
377-
cy.get('.cy-tooltip').should('contain', 'Copy to clipboard')
381+
it('copies project id config to clipboard', function () {
382+
cy.get('.action-copy').click()
383+
.then(() => {
384+
const expectedJsonConfig = {
385+
projectId: this.config.projectId,
386+
}
387+
const expectedCopyCommand = JSON.stringify(expectedJsonConfig, null, 2)
388+
389+
expect(this.ipc.setClipboardText).to.be.calledWith(expectedCopyCommand)
390+
})
391+
})
378392
})
379393

380-
it('copies project id config to clipboard', function () {
381-
cy.get('.action-copy').click()
382-
.then(() => {
383-
const expectedJsonConfig = {
384-
projectId: this.config.projectId,
385-
}
386-
const expectedCopyCommand = JSON.stringify(expectedJsonConfig, null, 2)
394+
context('with js file', () => {
395+
beforeEach(function () {
396+
this.openProject.resolve({ ...this.config, configFile: 'custom.cypress.js' })
397+
this.projectStatuses[0].id = this.config.projectId
398+
this.getProjectStatus.resolve(this.projectStatuses[0])
399+
400+
this.goToSettings()
401+
cy.contains('Project ID').click()
402+
})
387403

388-
expect(this.ipc.setClipboardText).to.be.calledWith(expectedCopyCommand)
404+
it('displays project id section', function () {
405+
cy.get('[data-cy="project-id"] pre').contains('module.exports = {')
406+
cy.percySnapshot()
389407
})
390408
})
391409
})
@@ -586,6 +604,17 @@ describe('Settings', () => {
586604
.should('contain', systemNodeVersion)
587605
.should('not.contain', bundledNodeVersion)
588606
})
607+
608+
it('should display an additional line when configFile is not JSON', function () {
609+
const configFile = 'notjson.js'
610+
611+
this.navigateWithConfig({
612+
configFile,
613+
})
614+
615+
cy.contains(`Node.js Version (${bundledNodeVersion})`).click()
616+
cy.get('.node-version li').should('contain', configFile)
617+
})
589618
})
590619

591620
describe('proxy settings panel', () => {

packages/desktop-gui/src/lib/config-file-formatted.jsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,14 @@ const configFileFormatted = (configFile) => {
66
return <><code>cypress.json</code> file (currently disabled by <code>--config-file false</code>)</>
77
}
88

9-
if (isUndefined(configFile) || configFile === 'cypress.json') {
9+
if (isUndefined(configFile)) {
1010
return <><code>cypress.json</code> file</>
1111
}
1212

13+
if (['cypress.json', 'cypress.config.js'].includes(configFile)) {
14+
return <><code>{configFile}</code> file</>
15+
}
16+
1317
return <>custom config file <code>{configFile}</code></>
1418
}
1519

packages/desktop-gui/src/lib/utils.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,5 @@ export function stripSharedDirsFromDir2 (dir1, dir2, osName) {
103103
.join(sep)
104104
.value()
105105
}
106+
107+
export const isFileJSON = (file) => file && /\.json$/.test(file)

packages/desktop-gui/src/settings/node-version.jsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { observer } from 'mobx-react'
33
import React from 'react'
44

55
import ipc from '../lib/ipc'
6+
import { isFileJSON } from '../lib/utils'
7+
import { configFileFormatted } from '../lib/config-file-formatted'
68

79
const openHelp = (e) => {
810
e.preventDefault()
@@ -89,6 +91,9 @@ const NodeVersion = observer(({ project }) => {
8991
<div className='well text-muted'>
9092
This Node.js version is used to:
9193
<ul>
94+
{isFileJSON(project.configFile)
95+
? undefined
96+
: <li>Execute code in the {configFileFormatted(project.configFile)}.</li>}
9297
<li>Build files in the {formatIntegrationFolder()} folder.</li>
9398
<li>Build files in the <code>cypress/support</code> folder.</li>
9499
<li>Execute code in the {formatPluginsFile() ? formatPluginsFile() : 'plugins'} file.</li>

packages/desktop-gui/src/settings/project-id.jsx

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import React from 'react'
33
import Tooltip from '@cypress/react-tooltip'
44

55
import ipc from '../lib/ipc'
6+
import { isFileJSON } from '../lib/utils'
67
import { configFileFormatted } from '../lib/config-file-formatted'
78

89
const openProjectIdHelp = (e) => {
@@ -19,10 +20,6 @@ const openProjectIdHelp = (e) => {
1920
const ProjectId = observer(({ project }) => {
2021
if (!project.id) return null
2122

22-
const projectIdJsonConfig = {
23-
projectId: project.id,
24-
}
25-
2623
return (
2724
<div data-cy="project-id">
2825
<a href='#' className='learn-more' onClick={openProjectIdHelp}>
@@ -33,7 +30,7 @@ const ProjectId = observer(({ project }) => {
3330
It identifies your project and should not be changed.
3431
</p>
3532
<pre className='line-nums copy-to-clipboard'>
36-
<a className="action-copy" onClick={() => ipc.setClipboardText(JSON.stringify(projectIdJsonConfig, null, 2))}>
33+
<a className="action-copy" onClick={() => ipc.setClipboardText(document.querySelector('[data-cy="project-id"] pre').innerText)}>
3734
<Tooltip
3835
title='Copy to clipboard'
3936
placement='top'
@@ -42,9 +39,20 @@ const ProjectId = observer(({ project }) => {
4239
<i className='fas fa-clipboard' />
4340
</Tooltip>
4441
</a>
45-
<span>{'{'}</span>
46-
<span>{` "projectId": "${project.id}"`}</span>
47-
<span>{'}'}</span>
42+
{
43+
isFileJSON(project.configFile) ?
44+
<>
45+
<span>{'{'}</span>
46+
<span>{` "projectId": "${project.id}"`}</span>
47+
<span>{'}'}</span>
48+
</>
49+
:
50+
<>
51+
<span>{'module.exports = {'}</span>
52+
<span>{` projectId: "${project.id}"`}</span>
53+
<span>{'}'}</span>
54+
</>
55+
}
4856
</pre>
4957
</div>
5058
)

packages/desktop-gui/src/settings/project-id_spec.jsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,14 @@ describe('ProjectId', () => {
4444

4545
cy.get('@externalOpen').should('have.been.called')
4646
})
47+
48+
it('shows a different output when configFile is js', () => {
49+
mount(<ProjectId project={{ ...project, configFile: 'cypress.config.js' }} />, {
50+
stylesheets: '/__root/dist/app.css',
51+
})
52+
53+
cy.get('[data-cy=project-id] pre').then(($pre) => {
54+
expect($pre.text()).to.contain('module.exports = ')
55+
})
56+
})
4757
})

packages/driver/cypress/integration/commands/actions/select_spec.js

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,14 @@ describe('src/cy/commands/actions/select', () => {
112112
})
113113
})
114114

115+
it('unselects all options if called with empty array', () => {
116+
cy.get('select[name=movies]').select(['apoc', 'br'])
117+
118+
cy.get('select[name=movies]').select([]).then(($select) => {
119+
expect($select.val()).to.deep.eq([])
120+
})
121+
})
122+
115123
// readonly should only be limited to inputs, not checkboxes
116124
it('can select a readonly select', () => {
117125
cy.get('select[name=hunter]').select('gon').then(($select) => {
@@ -505,17 +513,6 @@ describe('src/cy/commands/actions/select', () => {
505513
cy.get('select[name=foods]').select('')
506514
})
507515

508-
it('throws invalid array argument error when called with empty array', (done) => {
509-
cy.on('fail', (err) => {
510-
expect(err.message).to.include('`cy.select()` must be passed an array containing only strings and/or numbers. You passed: `[]`')
511-
expect(err.docsUrl).to.eq('https://on.cypress.io/select')
512-
513-
done()
514-
})
515-
516-
cy.get('select[name=foods]').select([])
517-
})
518-
519516
it('throws invalid array argument error when called with invalid array', (done) => {
520517
cy.on('fail', (err) => {
521518
expect(err.message).to.include('`cy.select()` must be passed an array containing only strings and/or numbers. You passed: `[true,false]`')

0 commit comments

Comments
 (0)