mirror of
https://github.com/cypress-io/cypress.git
synced 2026-02-27 03:19:22 -06:00
Merge remote-tracking branch 'origin/develop' into merge-develop-2-28-22
This commit is contained in:
@@ -1,15 +0,0 @@
|
||||
exports['list of all projects'] = [
|
||||
{
|
||||
"repo": "cypress-io/cypress-test-module-api",
|
||||
"provider": "circle",
|
||||
"platform": "linux"
|
||||
}
|
||||
]
|
||||
|
||||
exports['should have just circle and linux projects'] = [
|
||||
{
|
||||
"repo": "cypress-io/cypress-test-module-api",
|
||||
"provider": "circle",
|
||||
"platform": "linux"
|
||||
}
|
||||
]
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"chrome:beta": "99.0.4844.27",
|
||||
"chrome:beta": "99.0.4844.45",
|
||||
"chrome:stable": "98.0.4758.102"
|
||||
}
|
||||
|
||||
63
circle.yml
63
circle.yml
@@ -585,10 +585,16 @@ commands:
|
||||
steps:
|
||||
- restore_cached_binary
|
||||
- run:
|
||||
name: "Cloning test project: <<parameters.repo>>"
|
||||
name: "Cloning test project and checking out release branch: <<parameters.repo>>"
|
||||
working_directory: ~/
|
||||
command: |
|
||||
git clone --depth 1 --no-single-branch https://github.com/cypress-io/<<parameters.repo>>.git /tmp/<<parameters.repo>>
|
||||
cd /tmp/<<parameters.repo>> && (git checkout $(node ./scripts/get-next-version.js) || true)
|
||||
|
||||
# install some deps for get-next-version
|
||||
npm i semver@7.3.2 conventional-recommended-bump@6.1.0 conventional-changelog-angular@5.0.12
|
||||
NEXT_VERSION=$(node ./cypress/scripts/get-next-version.js)
|
||||
|
||||
cd /tmp/<<parameters.repo>> && (git checkout $NEXT_VERSION || true)
|
||||
- when:
|
||||
condition: <<parameters.pull_request_id>>
|
||||
steps:
|
||||
@@ -1749,39 +1755,6 @@ jobs:
|
||||
yarn cypress:run --project /tmp/cypress-test-tiny --record
|
||||
- store-npm-logs
|
||||
|
||||
test-binary-and-npm-against-other-projects:
|
||||
<<: *defaults
|
||||
parameters:
|
||||
<<: *defaultsParameters
|
||||
resource_class:
|
||||
type: string
|
||||
default: medium
|
||||
resource_class: << parameters.resource_class >>
|
||||
steps:
|
||||
# needs uploaded NPM and test binary
|
||||
- restore_cached_workspace
|
||||
- run: ls -la
|
||||
# make sure JSON files with uploaded urls are present
|
||||
- run: ls -la binary-url.json npm-package-url.json
|
||||
- run: cat binary-url.json
|
||||
- run: cat npm-package-url.json
|
||||
- run:
|
||||
# install NPM from unique urls
|
||||
name: Install Cypress Binary in Dummy Package
|
||||
command: |
|
||||
node scripts/test-unique-npm-and-binary.js \
|
||||
--npm npm-package-url.json \
|
||||
--binary binary-url.json \
|
||||
--cwd /tmp/testing
|
||||
- run:
|
||||
name: Running other test projects with new NPM package and binary
|
||||
command: |
|
||||
node scripts/test-other-projects.js \
|
||||
--npm npm-package-url.json \
|
||||
--binary binary-url.json \
|
||||
--provider circle
|
||||
- store-npm-logs
|
||||
|
||||
test-npm-module-and-verify-binary:
|
||||
<<: *defaults
|
||||
steps:
|
||||
@@ -2364,11 +2337,6 @@ linux-workflow: &linux-workflow
|
||||
- test-binary-against-kitchensink:
|
||||
requires:
|
||||
- create-build-artifacts
|
||||
- test-binary-and-npm-against-other-projects:
|
||||
context: test-runner:trigger-test-jobs
|
||||
<<: *mainBuildFilters
|
||||
requires:
|
||||
- create-build-artifacts
|
||||
- test-npm-module-and-verify-binary:
|
||||
<<: *mainBuildFilters
|
||||
requires:
|
||||
@@ -2459,13 +2427,6 @@ mac-workflow: &mac-workflow
|
||||
requires:
|
||||
- darwin-build
|
||||
|
||||
- test-binary-and-npm-against-other-projects:
|
||||
context: test-runner:trigger-test-jobs
|
||||
name: darwin-test-binary-and-npm-against-other-projects
|
||||
executor: mac
|
||||
requires:
|
||||
- darwin-create-build-artifacts
|
||||
|
||||
windows-workflow: &windows-workflow
|
||||
jobs:
|
||||
- node_modules_install:
|
||||
@@ -2521,14 +2482,6 @@ windows-workflow: &windows-workflow
|
||||
requires:
|
||||
- windows-build
|
||||
|
||||
- test-binary-and-npm-against-other-projects:
|
||||
context: test-runner:trigger-test-jobs
|
||||
name: windows-test-binary-and-npm-against-other-projects
|
||||
executor: windows
|
||||
resource_class: windows.medium
|
||||
requires:
|
||||
- windows-create-build-artifacts
|
||||
|
||||
workflows:
|
||||
linux:
|
||||
<<: *linux-workflow
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
"build": "node ./scripts/build.js",
|
||||
"dtslint": "dtslint types",
|
||||
"postinstall": "node ./scripts/post-install.js",
|
||||
"prerelease": "yarn build",
|
||||
"release": "cd build && releaser --no-node --no-changelog",
|
||||
"size": "t=\"cypress-v0.0.0.tgz\"; yarn pack --filename \"${t}\"; wc -c \"${t}\"; tar tvf \"${t}\"; rm \"${t}\";",
|
||||
"test": "yarn test-unit",
|
||||
"test-debug": "node --inspect-brk $(yarn bin mocha)",
|
||||
|
||||
@@ -111,14 +111,7 @@ In the following instructions, "X.Y.Z" is used to denote the [next version of Cy
|
||||
- Go into a project, run a quick test, make sure things look right
|
||||
- Install the new version into an established project and run the tests there
|
||||
- [cypress-realworld-app](https://github.com/cypress-io/cypress-realworld-app) uses yarn and represents a typical consumer implementation.
|
||||
- Optionally, do more thorough tests:
|
||||
- Trigger test projects from the command line (if you have the appropriate permissions)
|
||||
|
||||
```shell
|
||||
node scripts/test-other-projects.js --npm cypress@X.Y.Z --binary X.Y.Z
|
||||
```
|
||||
|
||||
- Test the new version of Cypress against the Cypress dashboard repo.
|
||||
- Optionally, do more thorough tests, for example test the new version of Cypress against the Cypress dashboard repo.
|
||||
|
||||
7. Confirm that every issue labeled [stage: pending release](https://github.com/cypress-io/cypress/issues?q=label%3A%22stage%3A+pending+release%22+is%3Aclosed) has a ZenHub release set. **Tip:** there is a command in [`release-automations`](https://github.com/cypress-io/release-automations)'s `issues-in-release` tool to list and check such issues. Without a ZenHub release issues will not be included in the right changelog.
|
||||
|
||||
|
||||
@@ -4,10 +4,10 @@ In `develop`, `master`, and any other branch configured in [`circle.yml`](../cir
|
||||
|
||||
Two main strategies are used to spawn these test projects:
|
||||
|
||||
1. Local CI
|
||||
1. `test-binary-against-repo` jobs
|
||||
2. Remote CI
|
||||
|
||||
## Local CI
|
||||
## `test-binary-against-repo` jobs
|
||||
|
||||
A number of CI jobs in `circle.yml` clone test projects and run tests as part of `cypress-io/cypress`'s CI pipeline.
|
||||
|
||||
@@ -17,30 +17,6 @@ Similarly to "Remote CI" test projects, Local CI test projects will attempt to c
|
||||
|
||||
One advantage to local CI is that it does not require creating commits to another repo.
|
||||
|
||||
## Remote CI
|
||||
## `binary-system-tests`
|
||||
|
||||
After the production binary and NPM package are build and uploaded in CI, [`/scripts/test-other-projects.js`](../scripts/test-other-projects.js) is run as part of the `test-other-projects` `circle.yml` step.
|
||||
|
||||
This script creates commits inside of several test projects (hence "Remote CI") in order to trigger a realistic, continous-integration test of Cypress.
|
||||
|
||||
For a list of the projects, see the definition of `_PROVIDERS` in [`/scripts/binary/bump.js`](../scripts/binary/bump.js).
|
||||
|
||||
For each project and operating system combo in `_PROVIDERS`, the script:
|
||||
|
||||
1. Creates a commit to the test project's GitHub repo using the API. [An example of such a commit.](https://github.com/cypress-io/cypress-test-tiny/commit/5b39f3f43f6b7598f0d57cffcba71a7048d1d809)
|
||||
* Note the commit is specifically for `linux`, and only the `linux-tests` job runs to completion.
|
||||
* If a branch exists that is named after the [next version](./next-version.md) (`X.Y.Z`), the commit will be made to that branch.
|
||||
* This is useful to test a release's breaking changes or new features against an example project without having to have the project's main branch in a broken state.
|
||||
* Otherwise, the default branch is used for the commit.
|
||||
2. Creates a status check in this GitHub repo (`cypress-io/cypress`) and marks it `pending`.
|
||||
3. Waits for the test project's CI workflow to finish running.
|
||||
* Each test project is configured to use [`@cypress/commit-message-install`](https://github.com/cypress-io/commit-message-install) to configure the exact test required via the information in the commit message.
|
||||
* Each test project is configured to update the `pending` CI job in `cypress-io/cypress` to a `success` when the CI workflow successfully finishes.
|
||||
|
||||
These tests add coverage to the Cypress code base by:
|
||||
|
||||
* Providing a super-close-to-real-world usage of Cypress (i.e. installing fresh from an NPM package and running in a bare repo using the repo's CI setup)
|
||||
* Testing in a variety of environments
|
||||
* Different Node.js versions
|
||||
* Different operating systems
|
||||
* A multitude of CI providers
|
||||
System tests in `/system-tests/test-binary` are run against the built Cypress App in CI. For more details, see the [README](../system-tests/README.md).
|
||||
@@ -14,7 +14,6 @@
|
||||
"binary-zip": "node ./scripts/binary.js zip",
|
||||
"build": "lerna run build --stream --no-bail --ignore create-cypress-tests --ignore \"'@packages/{runner}'\" && lerna run build --stream --scope create-cypress-tests",
|
||||
"build-prod": "lerna run build-prod-ui --stream && lerna run build-prod --stream --ignore create-cypress-tests && lerna run build-prod --stream --scope create-cypress-tests",
|
||||
"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 || echo 'ok, errors while cleaning'",
|
||||
@@ -76,7 +75,6 @@
|
||||
"nvm": "0.0.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@cypress/bumpercar": "2.0.12",
|
||||
"@cypress/commit-message-install": "3.1.3",
|
||||
"@cypress/env-or-json-file": "2.0.0",
|
||||
"@cypress/github-commit-status-check": "1.5.0",
|
||||
@@ -188,7 +186,6 @@
|
||||
"lint-staged": "11.1.2",
|
||||
"listr2": "3.8.3",
|
||||
"lodash": "^4.17.21",
|
||||
"make-empty-github-commit": "https://github.com/cypress-io/make-empty-github-commit.git#4a592aedb776ba2f4cc88979055315a53eec42ee",
|
||||
"minimist": "1.2.5",
|
||||
"mocha": "3.5.3",
|
||||
"mocha-banner": "1.1.2",
|
||||
@@ -196,7 +193,6 @@
|
||||
"mocha-multi-reporters": "1.1.7",
|
||||
"mock-fs": "5.1.1",
|
||||
"p-defer": "^3.0.0",
|
||||
"parse-github-repo-url": "1.4.1",
|
||||
"patch-package": "6.4.7",
|
||||
"plist": "3.0.4",
|
||||
"pluralize": "8.0.0",
|
||||
|
||||
@@ -593,199 +593,6 @@ 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/click-event-by-type.html')
|
||||
})
|
||||
|
||||
describe('triggers', () => {
|
||||
const targets = [
|
||||
'button-tag',
|
||||
'input-button',
|
||||
'input-image',
|
||||
'input-reset',
|
||||
'input-submit',
|
||||
]
|
||||
|
||||
targets.forEach((targetId) => {
|
||||
it(`${targetId}`, () => {
|
||||
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')
|
||||
cy.get('li').eq(2).should('have.text', 'click')
|
||||
cy.get('li').eq(3).should('have.text', 'keyup')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('does not trigger', () => {
|
||||
const targets = [
|
||||
'input-checkbox',
|
||||
'input-radio',
|
||||
]
|
||||
|
||||
targets.forEach((targetId) => {
|
||||
it(`${targetId}`, () => {
|
||||
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')
|
||||
cy.get('li').eq(2).should('have.text', 'keyup')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
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')
|
||||
@@ -1015,243 +822,6 @@ describe('src/cy/commands/actions/type - #type', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('events', () => {
|
||||
it('receives keydown event', (done) => {
|
||||
const $txt = cy.$$(':text:first')
|
||||
|
||||
$txt.on('keydown', (e) => {
|
||||
expect(_.toPlainObject(e.originalEvent)).to.include({
|
||||
altKey: false,
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
charCode: 0, // deprecated
|
||||
ctrlKey: false,
|
||||
detail: 0,
|
||||
key: 'a',
|
||||
// has code property https://github.com/cypress-io/cypress/issues/3722
|
||||
code: 'KeyA',
|
||||
keyCode: 65, // deprecated but fired by chrome always uppercase in the ASCII table
|
||||
location: 0,
|
||||
metaKey: false,
|
||||
repeat: false,
|
||||
shiftKey: false,
|
||||
type: 'keydown',
|
||||
which: 65, // deprecated but fired by chrome
|
||||
})
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
cy.get(':text:first').type('a')
|
||||
})
|
||||
|
||||
it('receives keypress event', (done) => {
|
||||
const $txt = cy.$$(':text:first')
|
||||
|
||||
$txt.on('keypress', (e) => {
|
||||
expect(_.toPlainObject(e.originalEvent)).to.include({
|
||||
altKey: false,
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
charCode: 97, // deprecated
|
||||
ctrlKey: false,
|
||||
detail: 0,
|
||||
key: 'a',
|
||||
code: 'KeyA',
|
||||
keyCode: 97, // deprecated
|
||||
location: 0,
|
||||
metaKey: false,
|
||||
repeat: false,
|
||||
shiftKey: false,
|
||||
type: 'keypress',
|
||||
which: 97, // deprecated
|
||||
})
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
cy.get(':text:first').type('a')
|
||||
})
|
||||
|
||||
it('receives keyup event', (done) => {
|
||||
const $txt = cy.$$(':text:first')
|
||||
|
||||
$txt.on('keyup', (e) => {
|
||||
expect(_.toPlainObject(e.originalEvent)).to.include({
|
||||
altKey: false,
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
charCode: 0, // deprecated
|
||||
ctrlKey: false,
|
||||
detail: 0,
|
||||
key: 'a',
|
||||
code: 'KeyA',
|
||||
keyCode: 65, // deprecated but fired by chrome always uppercase in the ASCII table
|
||||
location: 0,
|
||||
metaKey: false,
|
||||
repeat: false,
|
||||
shiftKey: false,
|
||||
type: 'keyup',
|
||||
view: cy.state('window'),
|
||||
which: 65, // deprecated but fired by chrome
|
||||
})
|
||||
.not.have.property('inputType')
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
cy.get(':text:first').type('a')
|
||||
})
|
||||
|
||||
it('receives textInput event', (done) => {
|
||||
const $txt = cy.$$(':text:first')
|
||||
|
||||
$txt[0].addEventListener('textInput', (e) => {
|
||||
// FIXME: (firefox) firefox cannot access window objects else throw cross-origin error
|
||||
expect(Object.prototype.toString.call(e.view)).eq('[object Window]')
|
||||
e.view = null
|
||||
expect(_.toPlainObject(e)).to.include({
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
data: 'a',
|
||||
detail: 0,
|
||||
type: 'textInput',
|
||||
// view: cy.state('window'),
|
||||
which: 0,
|
||||
})
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
cy.get(':text:first').type('a')
|
||||
})
|
||||
|
||||
it('receives input event', (done) => {
|
||||
const $txt = cy.$$(':text:first')
|
||||
|
||||
$txt.on('input', (e) => {
|
||||
const obj = _.pick(e.originalEvent, 'bubbles', 'cancelable', 'type')
|
||||
|
||||
expect(obj).to.deep.eq({
|
||||
bubbles: true,
|
||||
cancelable: false,
|
||||
type: 'input',
|
||||
})
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
cy.get(':text:first').type('a')
|
||||
})
|
||||
|
||||
it('fires events in the correct order')
|
||||
|
||||
it('fires events for each key stroke')
|
||||
|
||||
it('does fire input event when value changes', () => {
|
||||
const onInput = cy.stub()
|
||||
|
||||
cy.$$(':text:first').on('input', onInput)
|
||||
|
||||
cy.get(':text:first')
|
||||
.invoke('val', 'bar')
|
||||
.type('{selectAll}{rightarrow}{backspace}')
|
||||
.then(() => {
|
||||
expect(onInput).to.be.calledOnce
|
||||
})
|
||||
.then(() => {
|
||||
onInput.resetHistory()
|
||||
})
|
||||
|
||||
cy.get(':text:first')
|
||||
.invoke('val', 'bar')
|
||||
.type('{selectAll}{leftarrow}{del}')
|
||||
.then(() => {
|
||||
expect(onInput).to.be.calledOnce
|
||||
})
|
||||
.then(() => {
|
||||
onInput.resetHistory()
|
||||
})
|
||||
|
||||
cy.$$('[contenteditable]:first').on('input', onInput)
|
||||
|
||||
cy.get('[contenteditable]:first')
|
||||
.invoke('html', 'foobar')
|
||||
.type('{selectAll}{rightarrow}{backspace}')
|
||||
.then(() => {
|
||||
expect(onInput).to.be.calledOnce
|
||||
})
|
||||
.then(() => {
|
||||
onInput.resetHistory()
|
||||
})
|
||||
|
||||
cy.get('[contenteditable]:first')
|
||||
.invoke('html', 'foobar')
|
||||
.type('{selectAll}{leftarrow}{del}')
|
||||
.then(() => {
|
||||
expect(onInput).to.be.calledOnce
|
||||
})
|
||||
})
|
||||
|
||||
it('does not fire input event when value does not change', () => {
|
||||
let fired = false
|
||||
|
||||
cy.$$(':text:first').on('input', () => {
|
||||
fired = true
|
||||
})
|
||||
|
||||
cy.get(':text:first')
|
||||
.invoke('val', 'bar')
|
||||
.type('{selectAll}{rightarrow}{del}')
|
||||
.then(() => {
|
||||
expect(fired).to.eq(false)
|
||||
})
|
||||
|
||||
cy.get(':text:first')
|
||||
.invoke('val', 'bar')
|
||||
.type('{selectAll}{leftarrow}{backspace}')
|
||||
.then(() => {
|
||||
expect(fired).to.eq(false)
|
||||
})
|
||||
|
||||
cy.$$('textarea:first').on('input', () => {
|
||||
fired = true
|
||||
})
|
||||
|
||||
cy.get('textarea:first')
|
||||
.invoke('val', 'bar')
|
||||
.type('{selectAll}{rightarrow}{del}')
|
||||
.then(() => {
|
||||
expect(fired).to.eq(false)
|
||||
})
|
||||
|
||||
cy.get('textarea:first')
|
||||
.invoke('val', 'bar')
|
||||
.type('{selectAll}{leftarrow}{backspace}')
|
||||
.then(() => {
|
||||
expect(fired).to.eq(false)
|
||||
})
|
||||
|
||||
cy.$$('[contenteditable]:first').on('input', () => {
|
||||
fired = true
|
||||
})
|
||||
|
||||
cy.get('[contenteditable]:first')
|
||||
.invoke('html', 'foobar')
|
||||
.type('{movetoend}')
|
||||
.then(($el) => {
|
||||
expect(fired).to.eq(false)
|
||||
})
|
||||
|
||||
cy.get('[contenteditable]:first')
|
||||
.invoke('html', 'foobar')
|
||||
.type('{selectAll}{leftarrow}{backspace}')
|
||||
.then(() => {
|
||||
expect(fired).to.eq(false)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('maxlength', () => {
|
||||
it('limits text entered to the maxlength attribute of a text input', () => {
|
||||
const $input = cy.$$(':text:first')
|
||||
@@ -2912,337 +2482,6 @@ describe('src/cy/commands/actions/type - #type', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('click events', () => {
|
||||
it('passes timeout and interval down to click', (done) => {
|
||||
const input = $('<input />').attr('id', 'input-covered-in-span').prependTo(cy.$$('body'))
|
||||
|
||||
$('<span>span on input</span>')
|
||||
.css({
|
||||
position: 'absolute',
|
||||
left: input.offset().left,
|
||||
top: input.offset().top,
|
||||
padding: 5,
|
||||
display: 'inline-block',
|
||||
backgroundColor: 'yellow',
|
||||
})
|
||||
.prependTo(cy.$$('body'))
|
||||
|
||||
cy.on('command:retry', (options) => {
|
||||
expect(options.timeout).to.eq(1000)
|
||||
expect(options.interval).to.eq(60)
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
cy.get('#input-covered-in-span').type('foobar', { timeout: 1000, interval: 60 })
|
||||
})
|
||||
|
||||
it('does not issue another click event between type/type', () => {
|
||||
const clicked = cy.stub()
|
||||
|
||||
cy.$$(':text:first').click(clicked)
|
||||
|
||||
cy.get(':text:first').type('f').type('o').then(() => {
|
||||
expect(clicked).to.be.calledOnce
|
||||
})
|
||||
})
|
||||
|
||||
it('does not issue another click event if element is already in focus from click', () => {
|
||||
const clicked = cy.stub()
|
||||
|
||||
cy.$$(':text:first').click(clicked)
|
||||
|
||||
cy.get(':text:first').click().type('o').then(() => {
|
||||
expect(clicked).to.be.calledOnce
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('change events', () => {
|
||||
it('fires when enter is pressed and value has changed', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$(':text:first').change(changed)
|
||||
|
||||
cy.get(':text:first').invoke('val', 'foo').type('bar{enter}').then(() => {
|
||||
expect(changed).to.be.calledOnce
|
||||
})
|
||||
})
|
||||
|
||||
it('fires twice when enter is pressed and then again after losing focus', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$(':text:first').change(changed)
|
||||
|
||||
cy.get(':text:first').invoke('val', 'foo').type('bar{enter}baz').blur().then(() => {
|
||||
expect(changed).to.be.calledTwice
|
||||
})
|
||||
})
|
||||
|
||||
it('fires when element loses focus due to another action (click)', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$(':text:first').change(changed)
|
||||
|
||||
cy
|
||||
.get(':text:first').type('foo').then(() => {
|
||||
expect(changed).not.to.be.called
|
||||
})
|
||||
.get('button:first').click().then(() => {
|
||||
expect(changed).to.be.calledOnce
|
||||
})
|
||||
})
|
||||
|
||||
it('fires when element loses focus due to another action (type)', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$(':text:first').change(changed)
|
||||
|
||||
cy
|
||||
.get(':text:first').type('foo').then(() => {
|
||||
expect(changed).not.to.be.called
|
||||
})
|
||||
.get('textarea:first').type('bar').then(() => {
|
||||
expect(changed).to.be.calledOnce
|
||||
})
|
||||
})
|
||||
|
||||
it('fires when element is directly blurred', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$(':text:first').change(changed)
|
||||
|
||||
cy
|
||||
.get(':text:first').type('foo').blur().then(() => {
|
||||
expect(changed).to.be.calledOnce
|
||||
})
|
||||
})
|
||||
|
||||
it('fires when element is tabbed away from')//, ->
|
||||
// changed = 0
|
||||
|
||||
// cy.$$(":text:first").change ->
|
||||
// changed += 1
|
||||
|
||||
// cy.get(":text:first").invoke("val", "foo").type("b{tab}").then ->
|
||||
// expect(changed).to.eq 1
|
||||
|
||||
it('does not fire twice if element is already in focus between type/type', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$(':text:first').change(changed)
|
||||
|
||||
cy.get(':text:first').invoke('val', 'foo').type('f').type('o{enter}').then(() => {
|
||||
expect(changed).to.be.calledOnce
|
||||
})
|
||||
})
|
||||
|
||||
it('does not fire twice if element is already in focus between clear/type', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$(':text:first').change(changed)
|
||||
|
||||
cy.get(':text:first').invoke('val', 'foo').clear().type('o{enter}').then(() => {
|
||||
expect(changed).to.be.calledOnce
|
||||
})
|
||||
})
|
||||
|
||||
it('does not fire twice if element is already in focus between click/type', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$(':text:first').change(changed)
|
||||
|
||||
cy.get(':text:first').invoke('val', 'foo').click().type('o{enter}').then(() => {
|
||||
expect(changed).to.be.calledOnce
|
||||
})
|
||||
})
|
||||
|
||||
it('does not fire twice if element is already in focus between type/click', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$(':text:first').change(changed)
|
||||
|
||||
cy.get(':text:first').invoke('val', 'foo').type('d{enter}').click().then(() => {
|
||||
expect(changed).to.be.calledOnce
|
||||
})
|
||||
})
|
||||
|
||||
it('does not fire at all between clear/type/click', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$(':text:first').change(changed)
|
||||
|
||||
cy.get(':text:first').invoke('val', 'foo').clear().type('o').click().then(($el) => {
|
||||
expect(changed).not.to.be.called
|
||||
|
||||
return $el
|
||||
}).blur()
|
||||
.then(() => {
|
||||
expect(changed).to.be.calledOnce
|
||||
})
|
||||
})
|
||||
|
||||
it('does not fire if {enter} is preventedDefault', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$(':text:first').keypress((e) => {
|
||||
if (e.which === 13) {
|
||||
e.preventDefault()
|
||||
}
|
||||
})
|
||||
|
||||
cy.$$(':text:first').change(changed)
|
||||
|
||||
cy.get(':text:first').invoke('val', 'foo').type('b{enter}').then(() => {
|
||||
expect(changed).not.to.be.called
|
||||
})
|
||||
})
|
||||
|
||||
it('does not fire when enter is pressed and value hasnt changed', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$(':text:first').change(changed)
|
||||
|
||||
cy.get(':text:first').invoke('val', 'foo').type('b{backspace}{enter}').then(() => {
|
||||
expect(changed).not.to.be.called
|
||||
})
|
||||
})
|
||||
|
||||
it('does not fire at the end of the type', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$(':text:first').change(changed)
|
||||
|
||||
cy
|
||||
.get(':text:first').type('foo').then(() => {
|
||||
expect(changed).not.to.be.called
|
||||
})
|
||||
})
|
||||
|
||||
it('does not fire change event if value hasnt actually changed', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$(':text:first').change(changed)
|
||||
|
||||
cy
|
||||
.get(':text:first').invoke('val', 'foo').type('{backspace}{backspace}oo{enter}').blur().then(() => {
|
||||
expect(changed).not.to.be.called
|
||||
})
|
||||
})
|
||||
|
||||
it('does not fire if mousedown is preventedDefault which prevents element from losing focus', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$(':text:first').change(changed)
|
||||
|
||||
cy.$$('textarea:first').mousedown(() => {
|
||||
return false
|
||||
})
|
||||
|
||||
cy
|
||||
.get(':text:first').invoke('val', 'foo').type('bar')
|
||||
.get('textarea:first').click().then(() => {
|
||||
expect(changed).not.to.be.called
|
||||
})
|
||||
})
|
||||
|
||||
it('does not fire hitting {enter} inside of a textarea', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$('textarea:first').change(changed)
|
||||
|
||||
cy
|
||||
.get('textarea:first').type('foo{enter}bar').then(() => {
|
||||
expect(changed).not.to.be.called
|
||||
})
|
||||
})
|
||||
|
||||
it('does not fire hitting {enter} inside of [contenteditable]', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$('[contenteditable]:first').change(changed)
|
||||
|
||||
cy
|
||||
.get('[contenteditable]:first').type('foo{enter}bar').then(() => {
|
||||
expect(changed).not.to.be.called
|
||||
})
|
||||
})
|
||||
|
||||
// [contenteditable] does not fire ANY change events ever.
|
||||
it('does not fire at ALL for [contenteditable]', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$('[contenteditable]:first').change(changed)
|
||||
|
||||
cy
|
||||
.get('[contenteditable]:first').type('foo')
|
||||
.get('button:first').click().then(() => {
|
||||
expect(changed).not.to.be.called
|
||||
})
|
||||
})
|
||||
|
||||
it('does not fire on .clear() without blur', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$('input:first').change(changed)
|
||||
|
||||
cy.get('input:first').invoke('val', 'foo')
|
||||
.clear()
|
||||
.then(($el) => {
|
||||
expect(changed).not.to.be.called
|
||||
|
||||
return $el
|
||||
}).type('foo')
|
||||
.blur()
|
||||
.then(() => {
|
||||
expect(changed).not.to.be.called
|
||||
})
|
||||
})
|
||||
|
||||
it('fires change for single value change inputs', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$('input[type="date"]:first').change(changed)
|
||||
|
||||
cy.get('input[type="date"]:first')
|
||||
.type('1959-09-13')
|
||||
.blur()
|
||||
.then(() => {
|
||||
expect(changed).to.be.calledOnce
|
||||
})
|
||||
})
|
||||
|
||||
it('does not fire change for non-change single value input', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$('input[type="date"]:first').change(changed)
|
||||
|
||||
cy.get('input[type="date"]:first')
|
||||
.invoke('val', '1959-09-13')
|
||||
.type('1959-09-13')
|
||||
.blur()
|
||||
.then(() => {
|
||||
expect(changed).not.to.be.called
|
||||
})
|
||||
})
|
||||
|
||||
it('does not fire change for type\'d change that restores value', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$('input:first').change(changed)
|
||||
|
||||
cy.get('input:first')
|
||||
.invoke('val', 'foo')
|
||||
.type('{backspace}o')
|
||||
.invoke('val', 'bar')
|
||||
.type('{backspace}r')
|
||||
.blur()
|
||||
.then(() => {
|
||||
expect(changed).not.to.be.called
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('single value change inputs', () => {
|
||||
// https://github.com/cypress-io/cypress/issues/5476
|
||||
it('fires all keyboard events', () => {
|
||||
|
||||
774
packages/driver/cypress/e2e/commands/actions/type_events_spec.js
Normal file
774
packages/driver/cypress/e2e/commands/actions/type_events_spec.js
Normal file
@@ -0,0 +1,774 @@
|
||||
const { _, $ } = Cypress
|
||||
|
||||
describe('src/cy/commands/actions/type - #type events', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('fixtures/dom.html')
|
||||
})
|
||||
|
||||
describe('keyboard events', () => {
|
||||
it('receives keydown event', (done) => {
|
||||
const $txt = cy.$$(':text:first')
|
||||
|
||||
$txt.on('keydown', (e) => {
|
||||
expect(_.toPlainObject(e.originalEvent)).to.include({
|
||||
altKey: false,
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
charCode: 0, // deprecated
|
||||
ctrlKey: false,
|
||||
detail: 0,
|
||||
key: 'a',
|
||||
// has code property https://github.com/cypress-io/cypress/issues/3722
|
||||
code: 'KeyA',
|
||||
keyCode: 65, // deprecated but fired by chrome always uppercase in the ASCII table
|
||||
location: 0,
|
||||
metaKey: false,
|
||||
repeat: false,
|
||||
shiftKey: false,
|
||||
type: 'keydown',
|
||||
which: 65, // deprecated but fired by chrome
|
||||
})
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
cy.get(':text:first').type('a')
|
||||
})
|
||||
|
||||
it('receives keypress event', (done) => {
|
||||
const $txt = cy.$$(':text:first')
|
||||
|
||||
$txt.on('keypress', (e) => {
|
||||
expect(_.toPlainObject(e.originalEvent)).to.include({
|
||||
altKey: false,
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
charCode: 97, // deprecated
|
||||
ctrlKey: false,
|
||||
detail: 0,
|
||||
key: 'a',
|
||||
code: 'KeyA',
|
||||
keyCode: 97, // deprecated
|
||||
location: 0,
|
||||
metaKey: false,
|
||||
repeat: false,
|
||||
shiftKey: false,
|
||||
type: 'keypress',
|
||||
which: 97, // deprecated
|
||||
})
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
cy.get(':text:first').type('a')
|
||||
})
|
||||
|
||||
it('receives keyup event', (done) => {
|
||||
const $txt = cy.$$(':text:first')
|
||||
|
||||
$txt.on('keyup', (e) => {
|
||||
expect(_.toPlainObject(e.originalEvent)).to.include({
|
||||
altKey: false,
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
charCode: 0, // deprecated
|
||||
ctrlKey: false,
|
||||
detail: 0,
|
||||
key: 'a',
|
||||
code: 'KeyA',
|
||||
keyCode: 65, // deprecated but fired by chrome always uppercase in the ASCII table
|
||||
location: 0,
|
||||
metaKey: false,
|
||||
repeat: false,
|
||||
shiftKey: false,
|
||||
type: 'keyup',
|
||||
view: cy.state('window'),
|
||||
which: 65, // deprecated but fired by chrome
|
||||
})
|
||||
.not.have.property('inputType')
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
cy.get(':text:first').type('a')
|
||||
})
|
||||
|
||||
it('receives textInput event', (done) => {
|
||||
const $txt = cy.$$(':text:first')
|
||||
|
||||
$txt[0].addEventListener('textInput', (e) => {
|
||||
// FIXME: (firefox) firefox cannot access window objects else throw cross-origin error
|
||||
expect(Object.prototype.toString.call(e.view)).eq('[object Window]')
|
||||
e.view = null
|
||||
expect(_.toPlainObject(e)).to.include({
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
data: 'a',
|
||||
detail: 0,
|
||||
type: 'textInput',
|
||||
// view: cy.state('window'),
|
||||
which: 0,
|
||||
})
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
cy.get(':text:first').type('a')
|
||||
})
|
||||
|
||||
it('receives input event', (done) => {
|
||||
const $txt = cy.$$(':text:first')
|
||||
|
||||
$txt.on('input', (e) => {
|
||||
const obj = _.pick(e.originalEvent, 'bubbles', 'cancelable', 'type')
|
||||
|
||||
expect(obj).to.deep.eq({
|
||||
bubbles: true,
|
||||
cancelable: false,
|
||||
type: 'input',
|
||||
})
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
cy.get(':text:first').type('a')
|
||||
})
|
||||
|
||||
// https://github.com/cypress-io/cypress/issues/20283
|
||||
// TODO: Implement tests below.
|
||||
it('fires events in the correct order')
|
||||
|
||||
it('fires events for each key stroke')
|
||||
|
||||
it('does fire input event when value changes', () => {
|
||||
const onInput = cy.stub()
|
||||
|
||||
cy.$$(':text:first').on('input', onInput)
|
||||
|
||||
cy.get(':text:first')
|
||||
.invoke('val', 'bar')
|
||||
.type('{selectAll}{rightarrow}{backspace}')
|
||||
.then(() => {
|
||||
expect(onInput).to.be.calledOnce
|
||||
})
|
||||
.then(() => {
|
||||
onInput.resetHistory()
|
||||
})
|
||||
|
||||
cy.get(':text:first')
|
||||
.invoke('val', 'bar')
|
||||
.type('{selectAll}{leftarrow}{del}')
|
||||
.then(() => {
|
||||
expect(onInput).to.be.calledOnce
|
||||
})
|
||||
.then(() => {
|
||||
onInput.resetHistory()
|
||||
})
|
||||
|
||||
cy.$$('[contenteditable]:first').on('input', onInput)
|
||||
|
||||
cy.get('[contenteditable]:first')
|
||||
.invoke('html', 'foobar')
|
||||
.type('{selectAll}{rightarrow}{backspace}')
|
||||
.then(() => {
|
||||
expect(onInput).to.be.calledOnce
|
||||
})
|
||||
.then(() => {
|
||||
onInput.resetHistory()
|
||||
})
|
||||
|
||||
cy.get('[contenteditable]:first')
|
||||
.invoke('html', 'foobar')
|
||||
.type('{selectAll}{leftarrow}{del}')
|
||||
.then(() => {
|
||||
expect(onInput).to.be.calledOnce
|
||||
})
|
||||
})
|
||||
|
||||
it('does not fire input event when value does not change', () => {
|
||||
let fired = false
|
||||
|
||||
cy.$$(':text:first').on('input', () => {
|
||||
fired = true
|
||||
})
|
||||
|
||||
cy.get(':text:first')
|
||||
.invoke('val', 'bar')
|
||||
.type('{selectAll}{rightarrow}{del}')
|
||||
.then(() => {
|
||||
expect(fired).to.eq(false)
|
||||
})
|
||||
|
||||
cy.get(':text:first')
|
||||
.invoke('val', 'bar')
|
||||
.type('{selectAll}{leftarrow}{backspace}')
|
||||
.then(() => {
|
||||
expect(fired).to.eq(false)
|
||||
})
|
||||
|
||||
cy.$$('textarea:first').on('input', () => {
|
||||
fired = true
|
||||
})
|
||||
|
||||
cy.get('textarea:first')
|
||||
.invoke('val', 'bar')
|
||||
.type('{selectAll}{rightarrow}{del}')
|
||||
.then(() => {
|
||||
expect(fired).to.eq(false)
|
||||
})
|
||||
|
||||
cy.get('textarea:first')
|
||||
.invoke('val', 'bar')
|
||||
.type('{selectAll}{leftarrow}{backspace}')
|
||||
.then(() => {
|
||||
expect(fired).to.eq(false)
|
||||
})
|
||||
|
||||
cy.$$('[contenteditable]:first').on('input', () => {
|
||||
fired = true
|
||||
})
|
||||
|
||||
cy.get('[contenteditable]:first')
|
||||
.invoke('html', 'foobar')
|
||||
.type('{movetoend}')
|
||||
.then(($el) => {
|
||||
expect(fired).to.eq(false)
|
||||
})
|
||||
|
||||
cy.get('[contenteditable]:first')
|
||||
.invoke('html', 'foobar')
|
||||
.type('{selectAll}{leftarrow}{backspace}')
|
||||
.then(() => {
|
||||
expect(fired).to.eq(false)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('click events', () => {
|
||||
it('passes timeout and interval down to click', (done) => {
|
||||
const input = $('<input />').attr('id', 'input-covered-in-span').prependTo(cy.$$('body'))
|
||||
|
||||
$('<span>span on input</span>')
|
||||
.css({
|
||||
position: 'absolute',
|
||||
left: input.offset().left,
|
||||
top: input.offset().top,
|
||||
padding: 5,
|
||||
display: 'inline-block',
|
||||
backgroundColor: 'yellow',
|
||||
})
|
||||
.prependTo(cy.$$('body'))
|
||||
|
||||
cy.on('command:retry', (options) => {
|
||||
expect(options.timeout).to.eq(1000)
|
||||
expect(options.interval).to.eq(60)
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
cy.get('#input-covered-in-span').type('foobar', { timeout: 1000, interval: 60 })
|
||||
})
|
||||
|
||||
it('does not issue another click event between type/type', () => {
|
||||
const clicked = cy.stub()
|
||||
|
||||
cy.$$(':text:first').click(clicked)
|
||||
|
||||
cy.get(':text:first').type('f').type('o').then(() => {
|
||||
expect(clicked).to.be.calledOnce
|
||||
})
|
||||
})
|
||||
|
||||
it('does not issue another click event if element is already in focus from click', () => {
|
||||
const clicked = cy.stub()
|
||||
|
||||
cy.$$(':text:first').click(clicked)
|
||||
|
||||
cy.get(':text:first').click().type('o').then(() => {
|
||||
expect(clicked).to.be.calledOnce
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('change events', () => {
|
||||
it('fires when enter is pressed and value has changed', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$(':text:first').change(changed)
|
||||
|
||||
cy.get(':text:first').invoke('val', 'foo').type('bar{enter}').then(() => {
|
||||
expect(changed).to.be.calledOnce
|
||||
})
|
||||
})
|
||||
|
||||
it('fires twice when enter is pressed and then again after losing focus', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$(':text:first').change(changed)
|
||||
|
||||
cy.get(':text:first').invoke('val', 'foo').type('bar{enter}baz').blur().then(() => {
|
||||
expect(changed).to.be.calledTwice
|
||||
})
|
||||
})
|
||||
|
||||
it('fires when element loses focus due to another action (click)', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$(':text:first').change(changed)
|
||||
|
||||
cy
|
||||
.get(':text:first').type('foo').then(() => {
|
||||
expect(changed).not.to.be.called
|
||||
})
|
||||
.get('button:first').click().then(() => {
|
||||
expect(changed).to.be.calledOnce
|
||||
})
|
||||
})
|
||||
|
||||
it('fires when element loses focus due to another action (type)', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$(':text:first').change(changed)
|
||||
|
||||
cy
|
||||
.get(':text:first').type('foo').then(() => {
|
||||
expect(changed).not.to.be.called
|
||||
})
|
||||
.get('textarea:first').type('bar').then(() => {
|
||||
expect(changed).to.be.calledOnce
|
||||
})
|
||||
})
|
||||
|
||||
it('fires when element is directly blurred', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$(':text:first').change(changed)
|
||||
|
||||
cy
|
||||
.get(':text:first').type('foo').blur().then(() => {
|
||||
expect(changed).to.be.calledOnce
|
||||
})
|
||||
})
|
||||
|
||||
// https://github.com/cypress-io/cypress/issues/20283
|
||||
// TODO: implement this test
|
||||
it('fires when element is tabbed away from')//, ->
|
||||
// changed = 0
|
||||
|
||||
// cy.$$(":text:first").change ->
|
||||
// changed += 1
|
||||
|
||||
// cy.get(":text:first").invoke("val", "foo").type("b{tab}").then ->
|
||||
// expect(changed).to.eq 1
|
||||
|
||||
it('does not fire twice if element is already in focus between type/type', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$(':text:first').change(changed)
|
||||
|
||||
cy.get(':text:first').invoke('val', 'foo').type('f').type('o{enter}').then(() => {
|
||||
expect(changed).to.be.calledOnce
|
||||
})
|
||||
})
|
||||
|
||||
it('does not fire twice if element is already in focus between clear/type', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$(':text:first').change(changed)
|
||||
|
||||
cy.get(':text:first').invoke('val', 'foo').clear().type('o{enter}').then(() => {
|
||||
expect(changed).to.be.calledOnce
|
||||
})
|
||||
})
|
||||
|
||||
it('does not fire twice if element is already in focus between click/type', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$(':text:first').change(changed)
|
||||
|
||||
cy.get(':text:first').invoke('val', 'foo').click().type('o{enter}').then(() => {
|
||||
expect(changed).to.be.calledOnce
|
||||
})
|
||||
})
|
||||
|
||||
it('does not fire twice if element is already in focus between type/click', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$(':text:first').change(changed)
|
||||
|
||||
cy.get(':text:first').invoke('val', 'foo').type('d{enter}').click().then(() => {
|
||||
expect(changed).to.be.calledOnce
|
||||
})
|
||||
})
|
||||
|
||||
it('does not fire at all between clear/type/click', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$(':text:first').change(changed)
|
||||
|
||||
cy.get(':text:first').invoke('val', 'foo').clear().type('o').click().then(($el) => {
|
||||
expect(changed).not.to.be.called
|
||||
|
||||
return $el
|
||||
}).blur()
|
||||
.then(() => {
|
||||
expect(changed).to.be.calledOnce
|
||||
})
|
||||
})
|
||||
|
||||
it('does not fire if {enter} is preventedDefault', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$(':text:first').keypress((e) => {
|
||||
if (e.which === 13) {
|
||||
e.preventDefault()
|
||||
}
|
||||
})
|
||||
|
||||
cy.$$(':text:first').change(changed)
|
||||
|
||||
cy.get(':text:first').invoke('val', 'foo').type('b{enter}').then(() => {
|
||||
expect(changed).not.to.be.called
|
||||
})
|
||||
})
|
||||
|
||||
it('does not fire when enter is pressed and value hasnt changed', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$(':text:first').change(changed)
|
||||
|
||||
cy.get(':text:first').invoke('val', 'foo').type('b{backspace}{enter}').then(() => {
|
||||
expect(changed).not.to.be.called
|
||||
})
|
||||
})
|
||||
|
||||
it('does not fire at the end of the type', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$(':text:first').change(changed)
|
||||
|
||||
cy
|
||||
.get(':text:first').type('foo').then(() => {
|
||||
expect(changed).not.to.be.called
|
||||
})
|
||||
})
|
||||
|
||||
it('does not fire change event if value hasnt actually changed', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$(':text:first').change(changed)
|
||||
|
||||
cy
|
||||
.get(':text:first').invoke('val', 'foo').type('{backspace}{backspace}oo{enter}').blur().then(() => {
|
||||
expect(changed).not.to.be.called
|
||||
})
|
||||
})
|
||||
|
||||
it('does not fire if mousedown is preventedDefault which prevents element from losing focus', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$(':text:first').change(changed)
|
||||
|
||||
cy.$$('textarea:first').mousedown(() => {
|
||||
return false
|
||||
})
|
||||
|
||||
cy
|
||||
.get(':text:first').invoke('val', 'foo').type('bar')
|
||||
.get('textarea:first').click().then(() => {
|
||||
expect(changed).not.to.be.called
|
||||
})
|
||||
})
|
||||
|
||||
it('does not fire hitting {enter} inside of a textarea', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$('textarea:first').change(changed)
|
||||
|
||||
cy
|
||||
.get('textarea:first').type('foo{enter}bar').then(() => {
|
||||
expect(changed).not.to.be.called
|
||||
})
|
||||
})
|
||||
|
||||
it('does not fire hitting {enter} inside of [contenteditable]', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$('[contenteditable]:first').change(changed)
|
||||
|
||||
cy
|
||||
.get('[contenteditable]:first').type('foo{enter}bar').then(() => {
|
||||
expect(changed).not.to.be.called
|
||||
})
|
||||
})
|
||||
|
||||
// [contenteditable] does not fire ANY change events ever.
|
||||
it('does not fire at ALL for [contenteditable]', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$('[contenteditable]:first').change(changed)
|
||||
|
||||
cy
|
||||
.get('[contenteditable]:first').type('foo')
|
||||
.get('button:first').click().then(() => {
|
||||
expect(changed).not.to.be.called
|
||||
})
|
||||
})
|
||||
|
||||
it('does not fire on .clear() without blur', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$('input:first').change(changed)
|
||||
|
||||
cy.get('input:first').invoke('val', 'foo')
|
||||
.clear()
|
||||
.then(($el) => {
|
||||
expect(changed).not.to.be.called
|
||||
|
||||
return $el
|
||||
}).type('foo')
|
||||
.blur()
|
||||
.then(() => {
|
||||
expect(changed).not.to.be.called
|
||||
})
|
||||
})
|
||||
|
||||
it('fires change for single value change inputs', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$('input[type="date"]:first').change(changed)
|
||||
|
||||
cy.get('input[type="date"]:first')
|
||||
.type('1959-09-13')
|
||||
.blur()
|
||||
.then(() => {
|
||||
expect(changed).to.be.calledOnce
|
||||
})
|
||||
})
|
||||
|
||||
it('does not fire change for non-change single value input', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$('input[type="date"]:first').change(changed)
|
||||
|
||||
cy.get('input[type="date"]:first')
|
||||
.invoke('val', '1959-09-13')
|
||||
.type('1959-09-13')
|
||||
.blur()
|
||||
.then(() => {
|
||||
expect(changed).not.to.be.called
|
||||
})
|
||||
})
|
||||
|
||||
it('does not fire change for type\'d change that restores value', () => {
|
||||
const changed = cy.stub()
|
||||
|
||||
cy.$$('input:first').change(changed)
|
||||
|
||||
cy.get('input:first')
|
||||
.invoke('val', 'foo')
|
||||
.type('{backspace}o')
|
||||
.invoke('val', 'bar')
|
||||
.type('{backspace}r')
|
||||
.blur()
|
||||
.then(() => {
|
||||
expect(changed).not.to.be.called
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
// https://github.com/cypress-io/cypress/issues/19541
|
||||
describe(`type('{enter}') and click event on button-like elements`, () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('fixtures/click-event-by-type.html')
|
||||
})
|
||||
|
||||
describe('triggers', () => {
|
||||
const targets = [
|
||||
'#target-button-tag',
|
||||
'#target-input-button',
|
||||
'#target-input-image',
|
||||
'#target-input-reset',
|
||||
'#target-input-submit',
|
||||
]
|
||||
|
||||
targets.forEach((target) => {
|
||||
it(target, () => {
|
||||
cy.get(target).focus().type('{enter}')
|
||||
|
||||
cy.get('li').should('have.length', 4)
|
||||
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', 'click')
|
||||
cy.get('li').eq(3).should('have.text', 'keyup')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('does not trigger', () => {
|
||||
const targets = [
|
||||
'#target-input-checkbox',
|
||||
'#target-input-radio',
|
||||
]
|
||||
|
||||
targets.forEach((target) => {
|
||||
it(target, () => {
|
||||
cy.get(target).focus().type('{enter}')
|
||||
|
||||
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(`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')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -1,11 +1,9 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import { allowTsModuleStubbing } from '../../support/helpers'
|
||||
|
||||
allowTsModuleStubbing()
|
||||
|
||||
import $stackUtils from '@packages/driver/src/cypress/stack_utils'
|
||||
import $errUtils from '@packages/driver/src/cypress/error_utils'
|
||||
import $errUtils, { CypressError } from '@packages/driver/src/cypress/error_utils'
|
||||
import $errorMessages from '@packages/driver/src/cypress/error_messages'
|
||||
|
||||
describe('driver/src/cypress/error_utils', () => {
|
||||
@@ -76,6 +74,7 @@ describe('driver/src/cypress/error_utils', () => {
|
||||
it('throws error when it is an error', () => {
|
||||
const err = new Error('Something unexpected')
|
||||
|
||||
// @ts-ignore
|
||||
err.extraProp = 'extra prop'
|
||||
const fn = () => {
|
||||
$errUtils.throwErr(err)
|
||||
@@ -117,6 +116,7 @@ describe('driver/src/cypress/error_utils', () => {
|
||||
|
||||
context('.errByPath', () => {
|
||||
beforeEach(() => {
|
||||
// @ts-ignore
|
||||
$errorMessages.__test_errors = {
|
||||
obj: {
|
||||
message: 'This is a simple error message',
|
||||
@@ -186,7 +186,7 @@ describe('driver/src/cypress/error_utils', () => {
|
||||
|
||||
describe('when message value is an object', () => {
|
||||
it('has correct name, message, and docs url when path exists', () => {
|
||||
const err = $errUtils.errByPath('__test_errors.obj')
|
||||
const err = $errUtils.errByPath('__test_errors.obj') as CypressError
|
||||
|
||||
expect(err.name).to.eq('CypressError')
|
||||
expect(err.message).to.include('This is a simple error message')
|
||||
@@ -196,7 +196,7 @@ describe('driver/src/cypress/error_utils', () => {
|
||||
it('uses args provided for the error', () => {
|
||||
const err = $errUtils.errByPath('__test_errors.obj_with_args', {
|
||||
foo: 'foo', bar: ['bar', 'qux'],
|
||||
})
|
||||
}) as CypressError
|
||||
|
||||
expect(err.message).to.include('This has args like \'foo\' and bar,qux')
|
||||
expect(err.docsUrl).to.include('https://on.link.io')
|
||||
@@ -205,7 +205,7 @@ describe('driver/src/cypress/error_utils', () => {
|
||||
it('handles args being used multiple times in message', () => {
|
||||
const err = $errUtils.errByPath('__test_errors.obj_with_multi_args', {
|
||||
foo: 'foo', bar: ['bar', 'qux'],
|
||||
})
|
||||
}) as CypressError
|
||||
|
||||
expect(err.message).to.include('This has args like \'foo\' and bar,qux, and \'foo\' is used twice')
|
||||
expect(err.docsUrl).to.include('https://on.link.io')
|
||||
@@ -214,7 +214,7 @@ describe('driver/src/cypress/error_utils', () => {
|
||||
it('formats markdown in the error message', () => {
|
||||
const err = $errUtils.errByPath('__test_errors.obj_with_markdown', {
|
||||
foo: 'foo', bar: ['bar', 'qux'],
|
||||
})
|
||||
}) as CypressError
|
||||
|
||||
expect(err.message).to.include('This has markdown like `foo`, *bar,qux*, **foo**, and _bar,qux_')
|
||||
expect(err.docsUrl).to.include('https://on.link.io')
|
||||
@@ -223,7 +223,7 @@ describe('driver/src/cypress/error_utils', () => {
|
||||
|
||||
describe('when message value is a string', () => {
|
||||
it('has correct name, message, and docs url', () => {
|
||||
const err = $errUtils.errByPath('__test_errors.str')
|
||||
const err = $errUtils.errByPath('__test_errors.str') as CypressError
|
||||
|
||||
expect(err.name).to.eq('CypressError')
|
||||
expect(err.message).to.include('This is a simple error message')
|
||||
@@ -299,7 +299,7 @@ describe('driver/src/cypress/error_utils', () => {
|
||||
})
|
||||
|
||||
it('has the right message and docs url', () => {
|
||||
const err = $errUtils.errByPath('__test_errors.fn_returns_obj')
|
||||
const err = $errUtils.errByPath('__test_errors.fn_returns_obj') as CypressError
|
||||
|
||||
expect(err.message).to.include('This is a simple error message')
|
||||
expect(err.docsUrl).to.include('https://on.link.io')
|
||||
@@ -310,7 +310,7 @@ describe('driver/src/cypress/error_utils', () => {
|
||||
it('uses them in the error message', () => {
|
||||
const err = $errUtils.errByPath('__test_errors.fn_returns_obj_with_args', {
|
||||
foo: 'foo', bar: ['bar', 'qux'],
|
||||
})
|
||||
}) as CypressError
|
||||
|
||||
expect(err.message).to.include('This has args like \'foo\' and bar,qux')
|
||||
expect(err.docsUrl).to.include('https://on.link.io')
|
||||
@@ -321,7 +321,7 @@ describe('driver/src/cypress/error_utils', () => {
|
||||
it('uses them in the error message', () => {
|
||||
const err = $errUtils.errByPath('__test_errors.fn_returns_obj_with_multi_args', {
|
||||
foo: 'foo', bar: ['bar', 'qux'],
|
||||
})
|
||||
}) as CypressError
|
||||
|
||||
expect(err.message).to.include('This has args like \'foo\' and bar,qux, and \'foo\' is used twice')
|
||||
expect(err.docsUrl).to.include('https://on.link.io')
|
||||
@@ -334,6 +334,7 @@ describe('driver/src/cypress/error_utils', () => {
|
||||
let fn
|
||||
|
||||
beforeEach(() => {
|
||||
// @ts-ignore
|
||||
$errorMessages.__test_errors = {
|
||||
test: 'Simple error {{message}}',
|
||||
}
|
||||
@@ -370,6 +371,7 @@ describe('driver/src/cypress/error_utils', () => {
|
||||
|
||||
context('.throwErrByPath', () => {
|
||||
it('looks up error and throws it', () => {
|
||||
// @ts-ignore
|
||||
$errorMessages.__test_error = 'simple error message'
|
||||
|
||||
const fn = () => $errUtils.throwErrByPath('__test_error')
|
||||
@@ -598,7 +600,7 @@ describe('driver/src/cypress/error_utils', () => {
|
||||
context('Error.captureStackTrace', () => {
|
||||
it('works - even where not natively support', () => {
|
||||
function removeMe2 () {
|
||||
const err = {}
|
||||
const err: Record<string, any> = {}
|
||||
|
||||
Error.captureStackTrace(err, removeMeAndAbove)
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import { validate, validateNoReadOnlyConfig } from '@packages/config'
|
||||
import _ from 'lodash'
|
||||
import $ from 'jquery'
|
||||
@@ -42,6 +40,15 @@ import * as resolvers from './cypress/resolvers'
|
||||
|
||||
const debug = debugFn('cypress:driver:cypress')
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
__cySkipValidateConfig: boolean
|
||||
Cypress: Cypress.Cypress
|
||||
Runner: any
|
||||
cy: Cypress.cy
|
||||
}
|
||||
}
|
||||
|
||||
const jqueryProxyFn = function (...args) {
|
||||
if (!this.cy) {
|
||||
$errUtils.throwErrByPath('miscellaneous.no_cy')
|
||||
@@ -56,7 +63,83 @@ const throwPrivateCommandInterface = (method) => {
|
||||
})
|
||||
}
|
||||
|
||||
interface BackendError extends Error {
|
||||
__stackCleaned__: boolean
|
||||
backend: boolean
|
||||
}
|
||||
|
||||
interface AutomationError extends Error {
|
||||
automation: boolean
|
||||
}
|
||||
|
||||
class $Cypress {
|
||||
cy: any
|
||||
chai: any
|
||||
mocha: any
|
||||
runner: any
|
||||
downloads: any
|
||||
Commands: any
|
||||
$autIframe: any
|
||||
onSpecReady: any
|
||||
events: any
|
||||
$: any
|
||||
arch: any
|
||||
spec: any
|
||||
version: any
|
||||
browser: any
|
||||
platform: any
|
||||
testingType: any
|
||||
state: any
|
||||
originalConfig: any
|
||||
config: any
|
||||
env: any
|
||||
getTestRetries: any
|
||||
Cookies: any
|
||||
ProxyLogging: any
|
||||
_onInitialize: any
|
||||
isCy: any
|
||||
log: any
|
||||
isBrowser: any
|
||||
emit: any
|
||||
emitThen: any
|
||||
emitMap: any
|
||||
|
||||
// attach to $Cypress to access
|
||||
// all of the constructors
|
||||
// to enable users to monkeypatch
|
||||
$Cypress = $Cypress
|
||||
Cy = $Cy
|
||||
Chainer = $Chainer
|
||||
Command = $Command
|
||||
dom = $dom
|
||||
errorMessages = $errorMessages
|
||||
Keyboard = $Keyboard
|
||||
Location = $Location
|
||||
Log = $Log
|
||||
LocalStorage = $LocalStorage
|
||||
Mocha = $Mocha
|
||||
resolveWindowReference = resolvers.resolveWindowReference
|
||||
resolveLocationReference = resolvers.resolveLocationReference
|
||||
Mouse = {
|
||||
create: createMouse,
|
||||
}
|
||||
|
||||
Runner = $Runner
|
||||
Server = $Server
|
||||
Screenshot = $Screenshot
|
||||
SelectorPlayground = $SelectorPlayground
|
||||
utils = $utils
|
||||
_ = _
|
||||
Blob = blobUtil
|
||||
Buffer = Buffer
|
||||
Promise = Promise
|
||||
minimatch = minimatch
|
||||
sinon = sinon
|
||||
lolex = fakeTimers
|
||||
|
||||
static $: any
|
||||
static utils: any
|
||||
|
||||
constructor (config = {}) {
|
||||
this.cy = null
|
||||
this.chai = null
|
||||
@@ -75,7 +158,7 @@ class $Cypress {
|
||||
this.setConfig(config)
|
||||
}
|
||||
|
||||
setConfig (config = {}) {
|
||||
setConfig (config: Record<string, any> = {}) {
|
||||
// config.remote
|
||||
// {
|
||||
// origin: "http://localhost:2020"
|
||||
@@ -144,7 +227,7 @@ class $Cypress {
|
||||
this.state = $SetterGetter.create({})
|
||||
this.originalConfig = _.cloneDeep(config)
|
||||
this.config = $SetterGetter.create(config, (config) => {
|
||||
if (!window.top.__cySkipValidateConfig) {
|
||||
if (!window.top!.__cySkipValidateConfig) {
|
||||
validateNoReadOnlyConfig(config, (errProperty) => {
|
||||
const errPath = this.state('runnable')
|
||||
? 'config.invalid_cypress_config_override'
|
||||
@@ -191,6 +274,8 @@ class $Cypress {
|
||||
|
||||
this.Cookies = $Cookies.create(config.namespace, d)
|
||||
|
||||
// TODO: Remove this after $Events functions are added to $Cypress.
|
||||
// @ts-ignore
|
||||
this.ProxyLogging = new ProxyLogging(this)
|
||||
|
||||
return this.action('cypress:config', config)
|
||||
@@ -216,15 +301,15 @@ class $Cypress {
|
||||
// Method to manually re-execute Runner (usually within $autIframe)
|
||||
// used mainly by Component Testing
|
||||
restartRunner () {
|
||||
if (!window.top.Cypress) {
|
||||
if (!window.top!.Cypress) {
|
||||
throw Error('Cannot re-run spec without Cypress')
|
||||
}
|
||||
|
||||
// MobX state is only available on the Runner instance
|
||||
// which is attached to the top level `window`
|
||||
// We avoid infinite restart loop by checking if not in a loading state.
|
||||
if (!window.top.Runner.state.isLoading) {
|
||||
window.top.Runner.emit('restart')
|
||||
if (!window.top!.Runner.state.isLoading) {
|
||||
window.top!.Runner.emit('restart')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,6 +334,8 @@ class $Cypress {
|
||||
this.events.proxyTo(this.cy)
|
||||
|
||||
$scriptUtils.runScripts(specWindow, scripts)
|
||||
// TODO: remove this after making the type of `runScripts` more specific.
|
||||
// @ts-ignore
|
||||
.catch((error) => {
|
||||
this.runner.onSpecError('error')({ error })
|
||||
})
|
||||
@@ -275,6 +362,8 @@ class $Cypress {
|
||||
return this.backend('firefox:window:focus')
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
})
|
||||
.then(() => {
|
||||
this.cy.initialize(this.$autIframe)
|
||||
@@ -589,7 +678,7 @@ class $Cypress {
|
||||
// attaching long stace traces
|
||||
// which otherwise make this err
|
||||
// unusably long
|
||||
const err = $errUtils.makeErrFromObj(e)
|
||||
const err = $errUtils.makeErrFromObj(e) as BackendError
|
||||
|
||||
err.__stackCleaned__ = true
|
||||
err.backend = true
|
||||
@@ -611,7 +700,7 @@ class $Cypress {
|
||||
const e = reply.error
|
||||
|
||||
if (e) {
|
||||
const err = $errUtils.makeErrFromObj(e)
|
||||
const err = $errUtils.makeErrFromObj(e) as AutomationError
|
||||
|
||||
err.automation = true
|
||||
|
||||
@@ -670,43 +759,8 @@ class $Cypress {
|
||||
}
|
||||
}
|
||||
|
||||
// // attach to $Cypress to access
|
||||
// // all of the constructors
|
||||
// // to enable users to monkeypatch
|
||||
$Cypress.prototype.$Cypress = $Cypress
|
||||
$Cypress.prototype.Cy = $Cy
|
||||
$Cypress.prototype.Chainer = $Chainer
|
||||
$Cypress.prototype.Cookies = $Cookies
|
||||
$Cypress.prototype.Command = $Command
|
||||
$Cypress.prototype.Commands = $Commands
|
||||
$Cypress.prototype.dom = $dom
|
||||
$Cypress.prototype.errorMessages = $errorMessages
|
||||
$Cypress.prototype.Keyboard = $Keyboard
|
||||
$Cypress.prototype.Location = $Location
|
||||
$Cypress.prototype.Log = $Log
|
||||
$Cypress.prototype.LocalStorage = $LocalStorage
|
||||
$Cypress.prototype.Mocha = $Mocha
|
||||
$Cypress.prototype.resolveWindowReference = resolvers.resolveWindowReference
|
||||
$Cypress.prototype.resolveLocationReference = resolvers.resolveLocationReference
|
||||
$Cypress.prototype.Mouse = {
|
||||
create: createMouse,
|
||||
}
|
||||
|
||||
$Cypress.prototype.Runner = $Runner
|
||||
$Cypress.prototype.Server = $Server
|
||||
$Cypress.prototype.Screenshot = $Screenshot
|
||||
$Cypress.prototype.SelectorPlayground = $SelectorPlayground
|
||||
$Cypress.prototype.utils = $utils
|
||||
$Cypress.prototype._ = _
|
||||
$Cypress.prototype.Blob = blobUtil
|
||||
$Cypress.prototype.Buffer = Buffer
|
||||
$Cypress.prototype.Promise = Promise
|
||||
$Cypress.prototype.minimatch = minimatch
|
||||
$Cypress.prototype.sinon = sinon
|
||||
$Cypress.prototype.lolex = fakeTimers
|
||||
|
||||
// // attaching these so they are accessible
|
||||
// // via the runner + integration spec helper
|
||||
// attaching these so they are accessible
|
||||
// via the runner + integration spec helper
|
||||
$Cypress.$ = $
|
||||
$Cypress.utils = $utils
|
||||
export default $Cypress
|
||||
|
||||
@@ -422,7 +422,11 @@ const preferredStackAndCodeFrameIndex = (err, userInvocationStack) => {
|
||||
return { stack, index }
|
||||
}
|
||||
|
||||
const enhanceStack = ({ err, userInvocationStack, projectRoot }) => {
|
||||
const enhanceStack = ({ err, userInvocationStack, projectRoot }: {
|
||||
err: any
|
||||
userInvocationStack?: any
|
||||
projectRoot?: any
|
||||
}) => {
|
||||
const { stack, index } = preferredStackAndCodeFrameIndex(err, userInvocationStack)
|
||||
const { sourceMapped, parsed } = $stackUtils.getSourceStack(stack, projectRoot)
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import _ from 'lodash'
|
||||
import $ from 'jquery'
|
||||
import clone from 'clone'
|
||||
@@ -86,7 +84,7 @@ const getSnapshotProps = (attrs) => {
|
||||
return _.pick(attrs, SNAPSHOT_PROPS)
|
||||
}
|
||||
|
||||
const countLogsByTests = function (tests = {}) {
|
||||
const countLogsByTests = function (tests: Record<string, any> = {}) {
|
||||
if (_.isEmpty(tests)) {
|
||||
return 0
|
||||
}
|
||||
@@ -96,7 +94,7 @@ const countLogsByTests = function (tests = {}) {
|
||||
.flatMap((test) => {
|
||||
return [test, test.prevAttempts]
|
||||
})
|
||||
.flatMap((tests) => {
|
||||
.flatMap<{id: number}>((tests) => {
|
||||
return [].concat(tests.agents, tests.routes, tests.commands)
|
||||
}).compact()
|
||||
.union([{ id: 0 }])
|
||||
@@ -219,11 +217,12 @@ const defaults = function (state, config, obj) {
|
||||
return obj
|
||||
}
|
||||
|
||||
// TODO: Change `Log` function to class.
|
||||
const Log = function (cy, state, config, obj) {
|
||||
obj = defaults(state, config, obj)
|
||||
|
||||
// private attributes of each log
|
||||
const attributes = {}
|
||||
const attributes: Record<string, any> = {}
|
||||
|
||||
return {
|
||||
get (attr) {
|
||||
@@ -267,7 +266,7 @@ const Log = function (cy, state, config, obj) {
|
||||
.value()
|
||||
},
|
||||
|
||||
set (key, val) {
|
||||
set (key, val?) {
|
||||
if (_.isString(key)) {
|
||||
obj = {}
|
||||
obj[key] = val
|
||||
@@ -318,7 +317,7 @@ const Log = function (cy, state, config, obj) {
|
||||
return _.pick(attributes, args)
|
||||
},
|
||||
|
||||
snapshot (name, options = {}) {
|
||||
snapshot (name?, options: any = {}) {
|
||||
// bail early and don't snapshot if we're in headless mode
|
||||
// or we're not storing tests
|
||||
if (!config('isInteractive') || (config('numTestsKeptInMemory') === 0)) {
|
||||
@@ -467,7 +466,7 @@ const Log = function (cy, state, config, obj) {
|
||||
attributes.consoleProps = function (...args) {
|
||||
const key = _this.get('event') ? 'Event' : 'Command'
|
||||
|
||||
const consoleObj = {}
|
||||
const consoleObj: Record<string, any> = {}
|
||||
|
||||
consoleObj[key] = _this.get('name')
|
||||
|
||||
@@ -497,6 +496,128 @@ const Log = function (cy, state, config, obj) {
|
||||
}
|
||||
}
|
||||
|
||||
function create (Cypress, cy, state, config) {
|
||||
counter = 0
|
||||
const logs = {}
|
||||
|
||||
const trigger = function (log, event) {
|
||||
// bail if we never fired our initial log event
|
||||
if (!log._hasInitiallyLogged) {
|
||||
return
|
||||
}
|
||||
|
||||
// bail if we've reset the logs due to a Cypress.abort
|
||||
if (!logs[log.get('id')]) {
|
||||
return
|
||||
}
|
||||
|
||||
const attrs = log.toJSON()
|
||||
|
||||
// only trigger this event if our last stored
|
||||
// emitted attrs do not match the current toJSON
|
||||
if (!_.isEqual(log._emittedAttrs, attrs)) {
|
||||
log._emittedAttrs = attrs
|
||||
|
||||
log.emit(event, attrs)
|
||||
|
||||
return Cypress.action(event, attrs, log)
|
||||
}
|
||||
}
|
||||
|
||||
const triggerLog = function (log) {
|
||||
log._hasInitiallyLogged = true
|
||||
|
||||
return trigger(log, 'command:log:added')
|
||||
}
|
||||
|
||||
const addToLogs = function (log) {
|
||||
const id = log.get('id')
|
||||
|
||||
logs[id] = true
|
||||
}
|
||||
|
||||
const logFn = function (options: any = {}) {
|
||||
if (!_.isObject(options)) {
|
||||
$errUtils.throwErrByPath('log.invalid_argument', { args: { arg: options } })
|
||||
}
|
||||
|
||||
const log = Log(cy, state, config, options)
|
||||
|
||||
// add event emitter interface
|
||||
$Events.extend(log)
|
||||
|
||||
const triggerStateChanged = () => {
|
||||
return trigger(log, 'command:log:changed')
|
||||
}
|
||||
|
||||
// only fire the log:state:changed event
|
||||
// as fast as every 4ms
|
||||
// @ts-ignore
|
||||
log.fireChangeEvent = _.debounce(triggerStateChanged, 4)
|
||||
|
||||
log.set(options)
|
||||
|
||||
// if snapshot was passed
|
||||
// in, go ahead and snapshot
|
||||
if (log.get('snapshot')) {
|
||||
log.snapshot()
|
||||
}
|
||||
|
||||
// if end was passed in
|
||||
// go ahead and end
|
||||
if (log.get('end')) {
|
||||
log.end()
|
||||
}
|
||||
|
||||
if (log.get('error')) {
|
||||
log.error(log.get('error'))
|
||||
}
|
||||
|
||||
log.wrapConsoleProps()
|
||||
|
||||
const onBeforeLog = state('onBeforeLog')
|
||||
|
||||
// dont trigger log if this function
|
||||
// explicitly returns false
|
||||
if (_.isFunction(onBeforeLog)) {
|
||||
if (onBeforeLog.call(cy, log) === false) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// set the log on the command
|
||||
const current = state('current')
|
||||
|
||||
if (current) {
|
||||
current.log(log)
|
||||
}
|
||||
|
||||
addToLogs(log)
|
||||
|
||||
if (options.sessionInfo) {
|
||||
Cypress.emit('session:add', log.toJSON())
|
||||
}
|
||||
|
||||
if (options.emitOnly) {
|
||||
return
|
||||
}
|
||||
|
||||
triggerLog(log)
|
||||
|
||||
// if not current state then the log is being run
|
||||
// with no command reference, so just end the log
|
||||
if (!current) {
|
||||
log.end()
|
||||
}
|
||||
|
||||
return log
|
||||
}
|
||||
|
||||
logFn._logs = logs
|
||||
|
||||
return logFn
|
||||
}
|
||||
|
||||
export default {
|
||||
reduceMemory,
|
||||
|
||||
@@ -512,124 +633,5 @@ export default {
|
||||
|
||||
setCounter,
|
||||
|
||||
create (Cypress, cy, state, config) {
|
||||
counter = 0
|
||||
const logs = {}
|
||||
|
||||
const trigger = function (log, event) {
|
||||
// bail if we never fired our initial log event
|
||||
if (!log._hasInitiallyLogged) {
|
||||
return
|
||||
}
|
||||
|
||||
// bail if we've reset the logs due to a Cypress.abort
|
||||
if (!logs[log.get('id')]) {
|
||||
return
|
||||
}
|
||||
|
||||
const attrs = log.toJSON()
|
||||
|
||||
// only trigger this event if our last stored
|
||||
// emitted attrs do not match the current toJSON
|
||||
if (!_.isEqual(log._emittedAttrs, attrs)) {
|
||||
log._emittedAttrs = attrs
|
||||
|
||||
log.emit(event, attrs)
|
||||
|
||||
return Cypress.action(event, attrs, log)
|
||||
}
|
||||
}
|
||||
|
||||
const triggerLog = function (log) {
|
||||
log._hasInitiallyLogged = true
|
||||
|
||||
return trigger(log, 'command:log:added')
|
||||
}
|
||||
|
||||
const addToLogs = function (log) {
|
||||
const id = log.get('id')
|
||||
|
||||
logs[id] = true
|
||||
}
|
||||
|
||||
const logFn = function (options = {}) {
|
||||
if (!_.isObject(options)) {
|
||||
$errUtils.throwErrByPath('log.invalid_argument', { args: { arg: options } })
|
||||
}
|
||||
|
||||
const log = Log(cy, state, config, options)
|
||||
|
||||
// add event emitter interface
|
||||
$Events.extend(log)
|
||||
|
||||
const triggerStateChanged = () => {
|
||||
return trigger(log, 'command:log:changed')
|
||||
}
|
||||
|
||||
// only fire the log:state:changed event
|
||||
// as fast as every 4ms
|
||||
log.fireChangeEvent = _.debounce(triggerStateChanged, 4)
|
||||
|
||||
log.set(options)
|
||||
|
||||
// if snapshot was passed
|
||||
// in, go ahead and snapshot
|
||||
if (log.get('snapshot')) {
|
||||
log.snapshot()
|
||||
}
|
||||
|
||||
// if end was passed in
|
||||
// go ahead and end
|
||||
if (log.get('end')) {
|
||||
log.end({ silent: true })
|
||||
}
|
||||
|
||||
if (log.get('error')) {
|
||||
log.error(log.get('error'), { silent: true })
|
||||
}
|
||||
|
||||
log.wrapConsoleProps()
|
||||
|
||||
const onBeforeLog = state('onBeforeLog')
|
||||
|
||||
// dont trigger log if this function
|
||||
// explicitly returns false
|
||||
if (_.isFunction(onBeforeLog)) {
|
||||
if (onBeforeLog.call(cy, log) === false) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// set the log on the command
|
||||
const current = state('current')
|
||||
|
||||
if (current) {
|
||||
current.log(log)
|
||||
}
|
||||
|
||||
addToLogs(log)
|
||||
|
||||
if (options.sessionInfo) {
|
||||
Cypress.emit('session:add', log.toJSON())
|
||||
}
|
||||
|
||||
if (options.emitOnly) {
|
||||
return
|
||||
}
|
||||
|
||||
triggerLog(log)
|
||||
|
||||
// if not current state then the log is being run
|
||||
// with no command reference, so just end the log
|
||||
if (!current) {
|
||||
log.end({ silent: true })
|
||||
}
|
||||
|
||||
return log
|
||||
}
|
||||
|
||||
logFn._logs = logs
|
||||
|
||||
return logFn
|
||||
},
|
||||
create,
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* eslint-disable prefer-rest-params */
|
||||
// @ts-nocheck
|
||||
import _ from 'lodash'
|
||||
import $errUtils from './error_utils'
|
||||
import $errUtils, { CypressError } from './error_utils'
|
||||
import $utils from './utils'
|
||||
import $stackUtils from './stack_utils'
|
||||
|
||||
@@ -11,7 +10,7 @@ import * as mocha from 'mocha'
|
||||
|
||||
const { getTestFromRunnable } = $utils
|
||||
|
||||
const Mocha = mocha.Mocha != null ? mocha.Mocha : mocha
|
||||
const Mocha = (mocha as any).Mocha != null ? (mocha as any).Mocha : mocha
|
||||
|
||||
const { Test, Runner, Runnable, Hook, Suite } = Mocha
|
||||
|
||||
@@ -33,8 +32,8 @@ const suiteAfterAll = Suite.prototype.afterAll
|
||||
const suiteAfterEach = Suite.prototype.afterEach
|
||||
|
||||
// don't let mocha pollute the global namespace
|
||||
delete window.mocha
|
||||
delete window.Mocha
|
||||
delete (window as any).mocha
|
||||
delete (window as any).Mocha
|
||||
|
||||
function invokeFnWithOriginalTitle (ctx, originalTitle, mochaArgs, fn, _testConfig) {
|
||||
const ret = fn.apply(ctx, mochaArgs)
|
||||
@@ -68,7 +67,7 @@ function overloadMochaFnForConfig (fnName, specWindow) {
|
||||
const origFn = subFn ? _fn[subFn] : _fn
|
||||
|
||||
if (args.length > 2 && _.isObject(args[1])) {
|
||||
const _testConfig = _.extend({}, args[1])
|
||||
const _testConfig = _.extend({}, args[1]) as any
|
||||
|
||||
const mochaArgs = [args[0], args[2]]
|
||||
|
||||
@@ -447,15 +446,18 @@ const patchSuiteHooks = (specWindow, config) => {
|
||||
let invocationStack = hook.invocationDetails?.stack
|
||||
|
||||
if (!hook.invocationDetails) {
|
||||
const invocationDetails = $stackUtils.getInvocationDetails(specWindow, config)
|
||||
const invocationDetails = $stackUtils.getInvocationDetails(specWindow, config)!
|
||||
|
||||
hook.invocationDetails = invocationDetails
|
||||
invocationStack = invocationDetails.stack
|
||||
}
|
||||
|
||||
if (this._condensedHooks) {
|
||||
throw $errUtils.errByPath('mocha.hook_registered_late', { hookTitle: fnName })
|
||||
.setUserInvocationStack(invocationStack)
|
||||
const err = $errUtils.errByPath('mocha.hook_registered_late', { hookTitle: fnName }) as CypressError
|
||||
|
||||
err.setUserInvocationStack(invocationStack)
|
||||
|
||||
throw err
|
||||
}
|
||||
|
||||
return hook
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
/* eslint-disable prefer-rest-params */
|
||||
/* globals Cypress */
|
||||
|
||||
// @ts-nocheck
|
||||
import _ from 'lodash'
|
||||
import dayjs from 'dayjs'
|
||||
import Promise from 'bluebird'
|
||||
@@ -12,7 +9,7 @@ import $errUtils from './error_utils'
|
||||
import $stackUtils from './stack_utils'
|
||||
import { getResolvedTestConfigOverride } from '../cy/testConfigOverrides'
|
||||
import debugFn from 'debug'
|
||||
import { Emissions } from '@packages/types'
|
||||
import type { Emissions } from '@packages/types'
|
||||
|
||||
const mochaCtxKeysRe = /^(_runnable|test)$/
|
||||
const betweenQuotesRe = /\"(.+?)\"/
|
||||
@@ -29,6 +26,10 @@ const RUNNABLE_PROPS = '_testConfig id order title _titlePath root hookName hook
|
||||
const debug = debugFn('cypress:driver:runner')
|
||||
const debugErrors = debugFn('cypress:driver:errors')
|
||||
|
||||
const duration = (before: Date, after: Date) => {
|
||||
return Number(before) - Number(after)
|
||||
}
|
||||
|
||||
const fire = (event, runnable, Cypress) => {
|
||||
debug('fire: %o', { event })
|
||||
if (runnable._fired == null) {
|
||||
@@ -104,6 +105,8 @@ const testAfterRun = (test, Cypress) => {
|
||||
// prevent loop comprehension
|
||||
return null
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
const setTestTimingsForHook = (test, hookName, obj) => {
|
||||
@@ -127,7 +130,7 @@ const setTestTimings = (test, name, obj) => {
|
||||
}
|
||||
|
||||
const setWallClockDuration = (test) => {
|
||||
return test.wallClockDuration = new Date() - test.wallClockStartedAt
|
||||
return test.wallClockDuration = duration(new Date(), test.wallClockStartedAt)
|
||||
}
|
||||
|
||||
// we need to optimize wrap by converting
|
||||
@@ -138,7 +141,7 @@ const wrap = (runnable) => {
|
||||
return $utils.reduceProps(runnable, RUNNABLE_PROPS)
|
||||
}
|
||||
|
||||
const wrapAll = (runnable) => {
|
||||
const wrapAll = (runnable): any => {
|
||||
return _.extend(
|
||||
{},
|
||||
$utils.reduceProps(runnable, RUNNABLE_PROPS),
|
||||
@@ -202,7 +205,7 @@ const eachHookInSuite = (suite, fn) => {
|
||||
|
||||
// iterates over a suite's tests (including nested suites)
|
||||
// and will return as soon as the callback is true
|
||||
const findTestInSuite = (suite, fn = _.identity) => {
|
||||
const findTestInSuite = (suite, fn: any = _.identity) => {
|
||||
for (const test of suite.tests) {
|
||||
if (fn(test)) {
|
||||
return test
|
||||
@@ -218,7 +221,7 @@ const findTestInSuite = (suite, fn = _.identity) => {
|
||||
}
|
||||
}
|
||||
|
||||
const findSuiteInSuite = (suite, fn = _.identity) => {
|
||||
const findSuiteInSuite = (suite, fn: any = _.identity) => {
|
||||
if (fn(suite)) {
|
||||
return suite
|
||||
}
|
||||
@@ -241,7 +244,7 @@ const suiteHasSuite = (suite, suiteId) => {
|
||||
}
|
||||
|
||||
// same as findTestInSuite but iterates backwards
|
||||
const findLastTestInSuite = (suite, fn = _.identity) => {
|
||||
const findLastTestInSuite = (suite, fn: any = _.identity) => {
|
||||
for (let i = suite.suites.length - 1; i >= 0; i--) {
|
||||
const test = findLastTestInSuite(suite.suites[i], fn)
|
||||
|
||||
@@ -260,7 +263,7 @@ const findLastTestInSuite = (suite, fn = _.identity) => {
|
||||
}
|
||||
|
||||
const getAllSiblingTests = (suite, getTestById) => {
|
||||
const tests = []
|
||||
const tests: any[] = []
|
||||
|
||||
suite.eachTest((testRunnable) => {
|
||||
// iterate through each of our suites tests.
|
||||
@@ -272,6 +275,8 @@ const getAllSiblingTests = (suite, getTestById) => {
|
||||
if (test) {
|
||||
return tests.push(test)
|
||||
}
|
||||
|
||||
return
|
||||
})
|
||||
|
||||
return tests
|
||||
@@ -301,7 +306,7 @@ const isLastSuite = (suite, tests) => {
|
||||
|
||||
// grab all of the suites from our filtered tests
|
||||
// including all of their ancestor suites!
|
||||
const suites = _.reduce(tests, (memo, test) => {
|
||||
const suites = _.reduce<any, any[]>(tests, (memo, test) => {
|
||||
let parent
|
||||
|
||||
while ((parent = test.parent)) {
|
||||
@@ -310,8 +315,7 @@ const isLastSuite = (suite, tests) => {
|
||||
}
|
||||
|
||||
return memo
|
||||
}
|
||||
, [])
|
||||
}, [])
|
||||
|
||||
// intersect them with our parent suites and see if the last one is us
|
||||
return _
|
||||
@@ -358,7 +362,7 @@ const overrideRunnerHook = (Cypress, _runner, getTestById, getTest, setTest, get
|
||||
const test = getTest()
|
||||
const allTests = getTests()
|
||||
|
||||
let shouldFireTestAfterRun = _.noop
|
||||
let shouldFireTestAfterRun = () => false
|
||||
|
||||
switch (name) {
|
||||
case 'afterEach':
|
||||
@@ -376,6 +380,8 @@ const overrideRunnerHook = (Cypress, _runner, getTestById, getTest, setTest, get
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
break
|
||||
@@ -396,7 +402,7 @@ const overrideRunnerHook = (Cypress, _runner, getTestById, getTest, setTest, get
|
||||
// due to already being run on top navigation
|
||||
// https://github.com/cypress-io/cypress/issues/9026
|
||||
if (!testIsActuallyInSuite) {
|
||||
return
|
||||
return false
|
||||
}
|
||||
|
||||
// 1. if we're the very last test in the entire allTests
|
||||
@@ -411,6 +417,8 @@ const overrideRunnerHook = (Cypress, _runner, getTestById, getTest, setTest, get
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
break
|
||||
@@ -450,7 +458,7 @@ const overrideRunnerHook = (Cypress, _runner, getTestById, getTest, setTest, get
|
||||
|
||||
const getTestResults = (tests) => {
|
||||
return _.map(tests, (test) => {
|
||||
const obj = _.pick(test, 'id', 'duration', 'state')
|
||||
const obj: Record<string, any> = _.pick(test, 'id', 'duration', 'state')
|
||||
|
||||
obj.title = test.originalTitle
|
||||
// TODO FIX THIS!
|
||||
@@ -488,7 +496,7 @@ const normalizeAll = (suite, initialTests = {}, setTestsById, setTests, onRunnab
|
||||
// we hand back a normalized object but also
|
||||
// create optimized lookups for the tests without
|
||||
// traversing through it multiple times
|
||||
const tests = {}
|
||||
const tests: Record<string, any> = {}
|
||||
const normalizedSuite = normalize(suite, tests, initialTests, onRunnable, onLogsById, getRunnableId, getHookId, getOnlyTestId, getOnlySuiteId, createEmptyOnlyTest)
|
||||
|
||||
if (setTestsById) {
|
||||
@@ -519,6 +527,8 @@ const normalizeAll = (suite, initialTests = {}, setTestsById, setTests, onRunnab
|
||||
}
|
||||
|
||||
normalizedSuite.runtimeConfig[key] = v
|
||||
|
||||
return
|
||||
})
|
||||
|
||||
return normalizedSuite
|
||||
@@ -660,6 +670,8 @@ const normalize = (runnable, tests, initialTests, onRunnable, onLogsById, getRun
|
||||
return normalizedChild
|
||||
}))
|
||||
}
|
||||
|
||||
return null
|
||||
})
|
||||
|
||||
return normalizedRunnable
|
||||
@@ -737,6 +749,8 @@ const normalize = (runnable, tests, initialTests, onRunnable, onLogsById, getRun
|
||||
|
||||
return normalizedChildSuite
|
||||
}
|
||||
|
||||
return null
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -1017,8 +1031,8 @@ export default {
|
||||
create: (specWindow, mocha, Cypress, cy, state) => {
|
||||
let _runnableId = 0
|
||||
let _hookId = 0
|
||||
let _uncaughtFn = null
|
||||
let _resumedAtTestIndex = null
|
||||
let _uncaughtFn: (() => never) | null = null
|
||||
let _resumedAtTestIndex: number | null = null
|
||||
|
||||
const _runner = mocha.getRunner()
|
||||
|
||||
@@ -1099,19 +1113,19 @@ export default {
|
||||
specWindow.addEventListener('unhandledrejection', onSpecError('unhandledrejection'))
|
||||
|
||||
// hold onto the _runnables for faster lookup later
|
||||
let _test = null
|
||||
let _tests = []
|
||||
let _testsById = {}
|
||||
const _testsQueue = []
|
||||
const _testsQueueById = {}
|
||||
let _test: any = null
|
||||
let _tests: any[] = []
|
||||
let _testsById: Record<string, any> = {}
|
||||
const _testsQueue: any[] = []
|
||||
const _testsQueueById: Record<string, any> = {}
|
||||
// only used during normalization
|
||||
const _runnables = []
|
||||
const _logsById = {}
|
||||
const _runnables: any[] = []
|
||||
const _logsById: Record<string, any> = {}
|
||||
let _emissions: Emissions = {
|
||||
started: {},
|
||||
ended: {},
|
||||
}
|
||||
let _startTime = null
|
||||
let _startTime: string | null = null
|
||||
let _onlyTestId = null
|
||||
let _onlySuiteId = null
|
||||
|
||||
@@ -1210,7 +1224,7 @@ export default {
|
||||
const r = runnable
|
||||
const isHook = r.type === 'hook'
|
||||
const isTest = r.type === 'test'
|
||||
const test = getTest() || getTestFromHook(runnable, getTestById)
|
||||
const test = getTest() || getTestFromHook(runnable)
|
||||
const hookName = isHook && getHookName(r)
|
||||
const isBeforeEachHook = isHook && !!hookName.match(/before each/)
|
||||
const isAfterEachHook = isHook && !!hookName.match(/after each/)
|
||||
@@ -1383,11 +1397,11 @@ export default {
|
||||
// runtime of a runnables fn execution duration
|
||||
// and also the run of the runnable:after:run:async event
|
||||
let lifecycleStart
|
||||
let wallClockEnd = null
|
||||
let fnDurationStart = null
|
||||
let fnDurationEnd = null
|
||||
let afterFnDurationStart = null
|
||||
let afterFnDurationEnd = null
|
||||
let wallClockEnd: Date | null = null
|
||||
let fnDurationStart: Date | null = null
|
||||
let fnDurationEnd: Date | null = null
|
||||
let afterFnDurationStart: Date | null = null
|
||||
let afterFnDurationEnd: Date | null = null
|
||||
|
||||
// when this is a hook, capture the real start
|
||||
// date so we can calculate our test's duration
|
||||
@@ -1433,12 +1447,12 @@ export default {
|
||||
// reset runnable duration to include lifecycle
|
||||
// and afterFn timings purely for the mocha runner.
|
||||
// this is what it 'feels' like to the user
|
||||
runnable.duration = wallClockEnd - wallClockStartedAt
|
||||
runnable.duration = duration(wallClockEnd, wallClockStartedAt)
|
||||
|
||||
setTestTimingsForHook(test, hookName, {
|
||||
hookId: runnable.hookId,
|
||||
fnDuration: fnDurationEnd - fnDurationStart,
|
||||
afterFnDuration: afterFnDurationEnd - afterFnDurationStart,
|
||||
fnDuration: duration(fnDurationEnd!, fnDurationStart!),
|
||||
afterFnDuration: duration(afterFnDurationEnd, afterFnDurationStart!),
|
||||
})
|
||||
|
||||
break
|
||||
@@ -1447,13 +1461,13 @@ export default {
|
||||
// if we are currently on a test then
|
||||
// recalculate its duration to be based
|
||||
// against that (purely for the mocha reporter)
|
||||
test.duration = wallClockEnd - test.wallClockStartedAt
|
||||
test.duration = duration(wallClockEnd, test.wallClockStartedAt)
|
||||
|
||||
// but still preserve its actual function
|
||||
// body duration for timings
|
||||
setTestTimings(test, 'test', {
|
||||
fnDuration: fnDurationEnd - fnDurationStart,
|
||||
afterFnDuration: afterFnDurationEnd - afterFnDurationStart,
|
||||
fnDuration: duration(fnDurationEnd!, fnDurationStart!),
|
||||
afterFnDuration: duration(afterFnDurationEnd!, afterFnDurationStart!),
|
||||
})
|
||||
|
||||
break
|
||||
@@ -1559,7 +1573,7 @@ export default {
|
||||
if (lifecycleStart) {
|
||||
// capture how long the lifecycle took as part
|
||||
// of the overall wallClockDuration of our test
|
||||
setTestTimings(test, 'lifecycle', new Date() - lifecycleStart)
|
||||
setTestTimings(test, 'lifecycle', duration(new Date(), lifecycleStart))
|
||||
}
|
||||
|
||||
// capture the moment we're about to invoke
|
||||
@@ -1665,6 +1679,8 @@ export default {
|
||||
if (attrs) {
|
||||
return $Log.getSnapshotProps(attrs)
|
||||
}
|
||||
|
||||
return
|
||||
},
|
||||
|
||||
resumeAtTest (id, emissions: Emissions = {}) {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import _ from 'lodash'
|
||||
|
||||
import $utils from './utils'
|
||||
@@ -13,8 +11,8 @@ const _reset = () => {
|
||||
screenshotOnRunFailure: true,
|
||||
blackout: [],
|
||||
overwrite: false,
|
||||
onBeforeScreenshot () {},
|
||||
onAfterScreenshot () {},
|
||||
onBeforeScreenshot ($el) {},
|
||||
onAfterScreenshot ($el, results) {},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,8 +109,8 @@ const validateAndSetCallback = (props, values, cmd, log, option) => {
|
||||
values[option] = value
|
||||
}
|
||||
|
||||
const validate = (props, cmd, log) => {
|
||||
const values = {}
|
||||
const validate = (props, cmd, log?) => {
|
||||
const values: Record<string, any> = {}
|
||||
|
||||
if (!_.isPlainObject(props)) {
|
||||
$errUtils.throwErrByPath('screenshot.invalid_arg', {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import _ from 'lodash'
|
||||
import Bluebird from 'bluebird'
|
||||
|
||||
@@ -14,7 +12,7 @@ const fetchScript = (scriptWindow, script) => {
|
||||
}
|
||||
|
||||
const extractSourceMap = ([script, contents]) => {
|
||||
script.fullyQualifiedUrl = `${window.top.location.origin}${script.relativeUrl}`.replace(/ /g, '%20')
|
||||
script.fullyQualifiedUrl = `${window.top!.location.origin}${script.relativeUrl}`.replace(/ /g, '%20')
|
||||
|
||||
const sourceMap = $sourceMapUtils.extractSourceMap(script, contents)
|
||||
|
||||
@@ -22,7 +20,7 @@ const extractSourceMap = ([script, contents]) => {
|
||||
.return([script, contents])
|
||||
}
|
||||
|
||||
const evalScripts = (specWindow, scripts = []) => {
|
||||
const evalScripts = (specWindow, scripts: any = []) => {
|
||||
_.each(scripts, ([script, contents]) => {
|
||||
specWindow.eval(`${contents}\n//# sourceURL=${script.fullyQualifiedUrl}`)
|
||||
})
|
||||
@@ -32,7 +30,7 @@ const evalScripts = (specWindow, scripts = []) => {
|
||||
|
||||
const runScriptsFromUrls = (specWindow, scripts) => {
|
||||
return Bluebird
|
||||
.map(scripts, (script) => fetchScript(specWindow, script))
|
||||
.map<any, any>(scripts, (script) => fetchScript(specWindow, script))
|
||||
.map(extractSourceMap)
|
||||
.then((scripts) => evalScripts(specWindow, scripts))
|
||||
}
|
||||
@@ -46,7 +44,7 @@ export default {
|
||||
// NOTE: since in evalScripts, scripts are evaluated in order,
|
||||
// we chose to respect this constraint here too.
|
||||
// indeed _.each goes through the array in order
|
||||
return Bluebird.each(scripts, (script) => script())
|
||||
return Bluebird.each(scripts, (script: any) => script())
|
||||
}
|
||||
|
||||
return runScriptsFromUrls(specWindow, scripts)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// @ts-nocheck
|
||||
import _ from 'lodash'
|
||||
import { SourceMapConsumer } from 'source-map'
|
||||
import Promise from 'bluebird'
|
||||
@@ -16,6 +15,7 @@ let sourceMapConsumers = {}
|
||||
const initializeSourceMapConsumer = (file, sourceMap) => {
|
||||
if (!sourceMap) return Promise.resolve(null)
|
||||
|
||||
// @ts-ignore
|
||||
SourceMapConsumer.initialize({
|
||||
'lib/mappings.wasm': mappingsWasm,
|
||||
})
|
||||
@@ -32,7 +32,7 @@ const extractSourceMap = (file, fileContents) => {
|
||||
|
||||
if (!sourceMapMatch) return null
|
||||
|
||||
const url = _.last(sourceMapMatch)
|
||||
const url = _.last(sourceMapMatch) as any
|
||||
const dataUrlMatch = url.match(regexDataUrl)
|
||||
|
||||
if (!dataUrlMatch) return null
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// See: ./errorScenarios.md for details about error messages and stack traces
|
||||
// @ts-nocheck
|
||||
import _ from 'lodash'
|
||||
import path from 'path'
|
||||
import errorStackParser from 'error-stack-parser'
|
||||
@@ -54,7 +53,7 @@ const stackWithLinesRemoved = (stack, cb) => {
|
||||
const stackWithLinesDroppedFromMarker = (stack, marker, includeLast = false) => {
|
||||
return stackWithLinesRemoved(stack, (lines) => {
|
||||
// drop lines above the marker
|
||||
const withAboveMarkerRemoved = _.dropWhile(lines, (line) => {
|
||||
const withAboveMarkerRemoved = _.dropWhile(lines, (line: any) => {
|
||||
return !_.includes(line, marker)
|
||||
})
|
||||
|
||||
@@ -98,6 +97,8 @@ const stackWithUserInvocationStackSpliced = (err, userInvocationStack): StackAnd
|
||||
}
|
||||
}
|
||||
|
||||
type InvocationDetails = LineDetail | {}
|
||||
|
||||
const getInvocationDetails = (specWindow, config) => {
|
||||
if (specWindow.Error) {
|
||||
let stack = (new specWindow.Error()).stack
|
||||
@@ -112,12 +113,14 @@ const getInvocationDetails = (specWindow, config) => {
|
||||
stack = stackWithLinesDroppedFromMarker(stack, '__cypress/tests', true)
|
||||
}
|
||||
|
||||
const details = getSourceDetailsForFirstLine(stack, config('projectRoot')) || {}
|
||||
const details: InvocationDetails = getSourceDetailsForFirstLine(stack, config('projectRoot')) || {};
|
||||
|
||||
details.stack = stack
|
||||
(details as any).stack = stack
|
||||
|
||||
return details
|
||||
return details as (InvocationDetails & { stack: any })
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
const getLanguageFromExtension = (filePath) => {
|
||||
@@ -242,7 +245,7 @@ const parseLine = (line) => {
|
||||
|
||||
if (!isStackLine) return
|
||||
|
||||
const parsed = errorStackParser.parse({ stack: line })[0]
|
||||
const parsed = errorStackParser.parse({ stack: line } as any)[0]
|
||||
|
||||
if (!parsed) return
|
||||
|
||||
@@ -272,7 +275,23 @@ const stripCustomProtocol = (filePath) => {
|
||||
return filePath.replace(customProtocolRegex, '')
|
||||
}
|
||||
|
||||
const getSourceDetailsForLine = (projectRoot, line) => {
|
||||
type LineDetail =
|
||||
{
|
||||
message: any
|
||||
whitespace: any
|
||||
} |
|
||||
{
|
||||
function: any
|
||||
fileUrl: any
|
||||
originalFile: any
|
||||
relativeFile: any
|
||||
absoluteFile: any
|
||||
line: any
|
||||
column: number
|
||||
whitespace: any
|
||||
}
|
||||
|
||||
const getSourceDetailsForLine = (projectRoot, line): LineDetail => {
|
||||
const whitespace = getWhitespace(line)
|
||||
const generatedDetails = parseLine(line)
|
||||
|
||||
@@ -327,7 +346,7 @@ const reconstructStack = (parsedStack) => {
|
||||
}).join('\n')
|
||||
}
|
||||
|
||||
const getSourceStack = (stack, projectRoot) => {
|
||||
const getSourceStack = (stack, projectRoot?) => {
|
||||
if (!_.isString(stack)) return {}
|
||||
|
||||
const getSourceDetailsWithStackUtil = _.partial(getSourceDetailsForLine, projectRoot)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// @ts-nocheck
|
||||
import _ from 'lodash'
|
||||
import capitalize from 'underscore.string/capitalize'
|
||||
import methods from 'methods'
|
||||
@@ -46,7 +45,7 @@ const USER_FRIENDLY_TYPE_DETECTORS = _.map([
|
||||
[_.stubTrue, 'unknown'],
|
||||
], ([fn, type]) => {
|
||||
return [fn, _.constant(type)]
|
||||
})
|
||||
}) as [(val: any) => boolean, (val: Function) => Function][]
|
||||
|
||||
export default {
|
||||
warning (msg) {
|
||||
@@ -78,7 +77,7 @@ export default {
|
||||
const item = [].concat(val)[0]
|
||||
|
||||
if ($jquery.isJquery(item)) {
|
||||
return item.first()
|
||||
return (item as JQuery<any>).first()
|
||||
}
|
||||
|
||||
return item
|
||||
@@ -154,7 +153,7 @@ export default {
|
||||
memo.push(`${`${key}`.toLowerCase()}: ${this.stringifyActual(value)}`)
|
||||
|
||||
return memo
|
||||
}, [])
|
||||
}, [] as string[])
|
||||
|
||||
return `{${str.join(', ')}}`
|
||||
},
|
||||
@@ -185,7 +184,7 @@ export default {
|
||||
if (_.isObject(value)) {
|
||||
// Cannot use $dom.isJquery here because it causes infinite recursion.
|
||||
if (value instanceof $) {
|
||||
return `jQuery{${value.length}}`
|
||||
return `jQuery{${(value as JQueryStatic).length}}`
|
||||
}
|
||||
|
||||
const len = _.keys(value).length
|
||||
@@ -396,7 +395,7 @@ export default {
|
||||
*/
|
||||
encodeBase64Unicode (str) {
|
||||
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, (match, p1) => {
|
||||
return String.fromCharCode(`0x${p1}`)
|
||||
return String.fromCharCode(Number(`0x${p1}`))
|
||||
}))
|
||||
},
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import $errUtils from './error_utils'
|
||||
|
||||
const isCypressHeaderRe = /^X-Cypress-/i
|
||||
@@ -15,6 +13,16 @@ const parseJSON = (text) => {
|
||||
// maybe rename this to XMLHttpRequest ?
|
||||
// so it shows up correctly as an instance in the console
|
||||
class XMLHttpRequest {
|
||||
xhr: any
|
||||
id: any
|
||||
url: any
|
||||
method: any
|
||||
status: any
|
||||
statusMessage: any
|
||||
request: any
|
||||
response: any
|
||||
duration: any
|
||||
|
||||
constructor (xhr) {
|
||||
this.xhr = xhr
|
||||
this.id = this.xhr.id
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// @ts-nocheck
|
||||
import $ from 'jquery'
|
||||
import _ from 'lodash'
|
||||
|
||||
@@ -8,6 +7,7 @@ const wrap = (obj) => {
|
||||
}
|
||||
|
||||
const query = (selector, context) => {
|
||||
// @ts-ignore
|
||||
return new $.fn.init(selector, context)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import $jquery from './jquery'
|
||||
import $document from './document'
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import _ from 'lodash'
|
||||
|
||||
// IE doesn't support Array.from or Map.prototype.keys
|
||||
@@ -8,7 +6,7 @@ const getMapKeys = (map) => {
|
||||
return Array.from(map.keys())
|
||||
}
|
||||
|
||||
const keys = []
|
||||
const keys: any[] = []
|
||||
|
||||
map.forEach((key) => {
|
||||
keys.push(key)
|
||||
@@ -18,6 +16,8 @@ const getMapKeys = (map) => {
|
||||
}
|
||||
|
||||
class LimitedMap extends Map {
|
||||
private _limit: number
|
||||
|
||||
constructor (limit = 100) {
|
||||
super()
|
||||
|
||||
|
||||
2
packages/driver/types/internal-types.d.ts
vendored
2
packages/driver/types/internal-types.d.ts
vendored
@@ -36,6 +36,8 @@ declare namespace Cypress {
|
||||
sinon: sinon.SinonApi
|
||||
utils: CypressUtils
|
||||
state: State
|
||||
|
||||
originalConfig: Record<string, any>
|
||||
}
|
||||
|
||||
interface CypressUtils {
|
||||
|
||||
@@ -1,268 +0,0 @@
|
||||
const _ = require('lodash')
|
||||
const Promise = require('bluebird')
|
||||
const bumpercar = require('@cypress/bumpercar')
|
||||
const path = require('path')
|
||||
const la = require('lazy-ass')
|
||||
const check = require('check-more-types')
|
||||
const { configFromEnvOrJsonFile, filenameToShellVariable } = require('@cypress/env-or-json-file')
|
||||
const makeEmptyGithubCommit = require('make-empty-github-commit')
|
||||
const parse = require('parse-github-repo-url')
|
||||
const { setCommitStatus } = require('@cypress/github-commit-status-check')
|
||||
|
||||
let car = null
|
||||
|
||||
// all the projects to trigger / run / change environment variables for
|
||||
const _PROVIDERS = {
|
||||
circle: {
|
||||
main: 'cypress-io/cypress',
|
||||
linux: [
|
||||
'cypress-io/cypress-test-module-api',
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
const remapProjects = function (projectsByProvider) {
|
||||
const list = []
|
||||
|
||||
_.mapValues(projectsByProvider, (provider, name) => {
|
||||
const remapPlatform = (platform, repos) => {
|
||||
return repos.forEach((repo) => {
|
||||
return list.push({
|
||||
repo,
|
||||
provider: name,
|
||||
platform,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
if (provider.win32) {
|
||||
remapPlatform('win32', provider.win32)
|
||||
}
|
||||
|
||||
if (provider.linux) {
|
||||
remapPlatform('linux', provider.linux)
|
||||
}
|
||||
|
||||
if (provider.darwin) {
|
||||
return remapPlatform('darwin', provider.darwin)
|
||||
}
|
||||
})
|
||||
|
||||
return list
|
||||
}
|
||||
|
||||
// make flat list of objects
|
||||
// {repo, provider, platform}
|
||||
const PROJECTS = remapProjects(_PROVIDERS)
|
||||
|
||||
const getCiConfig = function () {
|
||||
const key = path.join('scripts', 'support', 'ci.json')
|
||||
const config = configFromEnvOrJsonFile(key)
|
||||
|
||||
if (!config) {
|
||||
console.error('⛔️ Cannot find CI credentials')
|
||||
console.error('Using @cypress/env-or-json-file module')
|
||||
console.error('and filename', key)
|
||||
console.error('which is environment variable', filenameToShellVariable(key))
|
||||
throw new Error('CI config not found')
|
||||
}
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
const awaitEachProjectAndProvider = function (projects, fn, filter = (val) => val) {
|
||||
const creds = getCiConfig()
|
||||
|
||||
// configure a new Bumpercar
|
||||
const providers = {}
|
||||
|
||||
if (check.unemptyString(creds.githubToken)) {
|
||||
providers.travis = {
|
||||
githubToken: process.env.GH_TOKEN,
|
||||
}
|
||||
}
|
||||
|
||||
if (check.unemptyString(creds.circleToken)) {
|
||||
providers.circle = {
|
||||
circleToken: creds.circleToken,
|
||||
}
|
||||
}
|
||||
|
||||
const providerNames = Object.keys(providers)
|
||||
|
||||
console.log('configured providers', providerNames)
|
||||
la(check.not.empty(providerNames), 'empty list of providers')
|
||||
|
||||
car = bumpercar.create({ providers })
|
||||
|
||||
const filteredProjects = projects.filter(filter)
|
||||
|
||||
if (check.empty(filteredProjects)) {
|
||||
console.log('⚠️ zero filtered projects left after filtering')
|
||||
}
|
||||
|
||||
console.log('filtered projects:')
|
||||
console.table(filteredProjects)
|
||||
|
||||
return Promise.mapSeries(filteredProjects, (project) => {
|
||||
return fn(project.repo, project.provider, creds)
|
||||
})
|
||||
}
|
||||
|
||||
// do not trigger all projects if there is specific provider
|
||||
const getFilterByProvider = function (providerName, platformName) {
|
||||
return (val) => {
|
||||
if (providerName && val.provider !== providerName) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (platformName && val.platform !== platformName) {
|
||||
return false
|
||||
}
|
||||
|
||||
return val
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
_PROVIDERS,
|
||||
|
||||
remapProjects,
|
||||
|
||||
getFilterByProvider,
|
||||
|
||||
// in each project, set a couple of environment variables
|
||||
version (nameOrUrl, binaryVersionOrUrl, platform, providerName) {
|
||||
console.log('All possible projects:')
|
||||
console.table(PROJECTS)
|
||||
|
||||
la(check.unemptyString(nameOrUrl),
|
||||
'missing cypress name or url to set', nameOrUrl)
|
||||
|
||||
if (check.semver(nameOrUrl)) {
|
||||
console.log('for version', nameOrUrl)
|
||||
nameOrUrl = `cypress@${nameOrUrl}`
|
||||
console.log('full NPM install name is', nameOrUrl)
|
||||
}
|
||||
|
||||
la(check.unemptyString(binaryVersionOrUrl),
|
||||
'missing binary version or url', binaryVersionOrUrl)
|
||||
|
||||
const result = {
|
||||
versionName: nameOrUrl,
|
||||
binary: binaryVersionOrUrl,
|
||||
}
|
||||
|
||||
const projectFilter = getFilterByProvider(providerName)
|
||||
|
||||
const updateProject = function (project, provider) {
|
||||
console.log('setting environment variables in', project)
|
||||
|
||||
return car.updateProjectEnv(project, provider, {
|
||||
CYPRESS_NPM_PACKAGE_NAME: nameOrUrl,
|
||||
CYPRESS_INSTALL_BINARY: binaryVersionOrUrl,
|
||||
})
|
||||
}
|
||||
|
||||
return awaitEachProjectAndProvider(PROJECTS, updateProject, projectFilter)
|
||||
.then(() => result)
|
||||
},
|
||||
|
||||
// triggers test projects on multiple CIs
|
||||
// the test projects will exercise the new version of
|
||||
// the Cypress test runner we just built
|
||||
runTestProjects (getStatusAndMessage, providerName, version, platform) {
|
||||
const projectFilter = getFilterByProvider(providerName, platform)
|
||||
|
||||
const makeCommit = function (project, provider, creds) {
|
||||
// make empty commit to trigger CIs
|
||||
// project is owner/repo string like cypress-io/cypress-test-tiny
|
||||
console.log('making commit to project', project)
|
||||
|
||||
// print if we have a few github variables present
|
||||
console.log('do we have GH_APP_ID?', Boolean(process.env.GH_APP_ID))
|
||||
console.log('do we have GH_INSTALLATION_ID?', Boolean(process.env.GH_INSTALLATION_ID))
|
||||
console.log('do we have GH_PRIVATE_KEY?', Boolean(process.env.GH_PRIVATE_KEY))
|
||||
console.log('do we have GH_TOKEN?', Boolean(process.env.GH_TOKEN))
|
||||
|
||||
const parsedRepo = parse(project)
|
||||
const owner = parsedRepo[0]
|
||||
const repo = parsedRepo[1]
|
||||
|
||||
let { status, message } = getStatusAndMessage(repo)
|
||||
|
||||
if (!message) {
|
||||
message =
|
||||
`\
|
||||
Testing new Cypress version ${version}
|
||||
\
|
||||
`
|
||||
|
||||
if (process.env.CIRCLE_BUILD_URL) {
|
||||
message += '\n'
|
||||
message += `Circle CI build url ${process.env.CIRCLE_BUILD_URL}`
|
||||
}
|
||||
}
|
||||
|
||||
const defaultOptions = {
|
||||
owner,
|
||||
repo,
|
||||
message,
|
||||
token: process.env.GH_TOKEN,
|
||||
}
|
||||
|
||||
const createGithubCommitStatusCheck = function ({ sha }) {
|
||||
if (!status) {
|
||||
return
|
||||
}
|
||||
|
||||
// status is {owner, repo, sha} and maybe a few other properties
|
||||
const isStatus = check.schema({
|
||||
owner: check.unemptyString,
|
||||
repo: check.unemptyString,
|
||||
sha: check.commitId,
|
||||
context: check.unemptyString,
|
||||
platform: check.unemptyString,
|
||||
arch: check.unemptyString,
|
||||
})
|
||||
|
||||
if (!isStatus(status)) {
|
||||
console.error('Invalid status object %o', status)
|
||||
}
|
||||
|
||||
const targetUrl = `https://github.com/${owner}/${repo}/commit/${sha}`
|
||||
const commitStatusOptions = {
|
||||
targetUrl,
|
||||
owner: status.owner,
|
||||
repo: status.repo,
|
||||
sha: status.sha,
|
||||
context: status.context,
|
||||
state: 'pending',
|
||||
description: `${owner}/${repo}`,
|
||||
}
|
||||
|
||||
console.log(
|
||||
'creating commit status check',
|
||||
commitStatusOptions.description,
|
||||
commitStatusOptions.context,
|
||||
)
|
||||
|
||||
return setCommitStatus(commitStatusOptions)
|
||||
}
|
||||
|
||||
if (!version) {
|
||||
return makeEmptyGithubCommit(defaultOptions).then(createGithubCommitStatusCheck)
|
||||
}
|
||||
|
||||
// first try to commit to branch for next upcoming version
|
||||
return makeEmptyGithubCommit({ ...defaultOptions, branch: version })
|
||||
.catch(() => {
|
||||
// maybe there is no branch for next version
|
||||
// try default branch
|
||||
return makeEmptyGithubCommit(defaultOptions)
|
||||
}).then(createGithubCommitStatusCheck)
|
||||
}
|
||||
|
||||
return awaitEachProjectAndProvider(PROJECTS, makeCommit, projectFilter)
|
||||
},
|
||||
}
|
||||
@@ -16,7 +16,6 @@ const rp = require('@cypress/request-promise')
|
||||
|
||||
const zip = require('./zip')
|
||||
const ask = require('./ask')
|
||||
const bump = require('./bump')
|
||||
const meta = require('./meta')
|
||||
const build = require('./build')
|
||||
const upload = require('./upload')
|
||||
@@ -104,23 +103,6 @@ const deploy = {
|
||||
return opts
|
||||
},
|
||||
|
||||
bump () {
|
||||
return ask.whichBumpTask()
|
||||
.then((task) => {
|
||||
switch (task) {
|
||||
case 'run':
|
||||
return bump.runTestProjects()
|
||||
case 'version':
|
||||
return ask.whichVersion(meta.distDir(''))
|
||||
.then((v) => {
|
||||
return bump.version(v)
|
||||
})
|
||||
default:
|
||||
throw new Error('unknown task')
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
release () {
|
||||
// read off the argv
|
||||
const options = this.parseOptions(process.argv)
|
||||
|
||||
@@ -2,13 +2,14 @@
|
||||
|
||||
// See ../guides/next-version.md for documentation.
|
||||
|
||||
const path = require('path')
|
||||
const semver = require('semver')
|
||||
const Bluebird = require('bluebird')
|
||||
const bumpCb = require('conventional-recommended-bump')
|
||||
const { promisify } = require('util')
|
||||
|
||||
const currentVersion = require('../package.json').version
|
||||
|
||||
const bump = Bluebird.promisify(bumpCb)
|
||||
const bump = promisify(bumpCb)
|
||||
const paths = ['packages', 'cli']
|
||||
|
||||
let nextVersion
|
||||
@@ -30,14 +31,17 @@ if (require.main !== module) {
|
||||
return
|
||||
}
|
||||
|
||||
Bluebird.mapSeries(paths, async (path) => {
|
||||
const pathNextVersion = await getNextVersionForPath(path)
|
||||
(async () => {
|
||||
process.chdir(path.join(__dirname, '..'))
|
||||
|
||||
if (!nextVersion || semver.gt(pathNextVersion, nextVersion)) {
|
||||
nextVersion = pathNextVersion
|
||||
for (const path of paths) {
|
||||
const pathNextVersion = await getNextVersionForPath(path)
|
||||
|
||||
if (!nextVersion || semver.gt(pathNextVersion, nextVersion)) {
|
||||
nextVersion = pathNextVersion
|
||||
}
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
|
||||
if (!nextVersion) {
|
||||
throw new Error('Unable to determine next version.')
|
||||
}
|
||||
@@ -51,4 +55,4 @@ Bluebird.mapSeries(paths, async (path) => {
|
||||
}
|
||||
|
||||
console.log(nextVersion)
|
||||
})
|
||||
})()
|
||||
|
||||
@@ -1,139 +0,0 @@
|
||||
const la = require('lazy-ass')
|
||||
const is = require('check-more-types')
|
||||
const { getNameAndBinary, getJustVersion, getShortCommit } = require('./utils')
|
||||
const bump = require('./binary/bump')
|
||||
const { stripIndent } = require('common-tags')
|
||||
const os = require('os')
|
||||
const minimist = require('minimist')
|
||||
const { getInstallJson } = require('@cypress/commit-message-install')
|
||||
|
||||
/* eslint-disable no-console */
|
||||
|
||||
// See ../guides/testing-other-projects.md for documentation.
|
||||
|
||||
const { npm, binary } = getNameAndBinary(process.argv)
|
||||
|
||||
la(is.unemptyString(npm), 'missing npm url')
|
||||
la(is.unemptyString(binary), 'missing binary url')
|
||||
const platform = os.platform()
|
||||
const arch = os.arch()
|
||||
|
||||
console.log('bumping versions for other projects')
|
||||
console.log(' npm:', npm)
|
||||
console.log(' binary:', binary)
|
||||
console.log(' platform:', platform)
|
||||
console.log(' arch:', arch)
|
||||
|
||||
const cliOptions = minimist(process.argv, {
|
||||
string: 'provider',
|
||||
alias: {
|
||||
provider: 'p',
|
||||
},
|
||||
})
|
||||
|
||||
/**
|
||||
* Returns given string surrounded by ```json + ``` quotes
|
||||
* @param {string} s
|
||||
*/
|
||||
const toJsonCodeBlock = (s) => {
|
||||
const start = '```json'
|
||||
const finish = '```'
|
||||
|
||||
return `${start}\n${s}\n${finish}\n`
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts given JSON object into markdown text block
|
||||
* @param {object} object
|
||||
*/
|
||||
const toMarkdownJsonBlock = (object) => {
|
||||
la(object, 'expected an object to convert to JSON', object)
|
||||
const str = JSON.stringify(object, null, 2)
|
||||
|
||||
return toJsonCodeBlock(str)
|
||||
}
|
||||
|
||||
console.log('starting each test projects')
|
||||
|
||||
const shortNpmVersion = getJustVersion(npm)
|
||||
|
||||
console.log('short NPM version', shortNpmVersion)
|
||||
|
||||
let subject = `Testing new ${platform} ${arch} Cypress version ${shortNpmVersion}`
|
||||
const commitInfo = getShortCommit()
|
||||
|
||||
if (commitInfo) {
|
||||
subject += ` ${commitInfo.short}`
|
||||
}
|
||||
|
||||
// instructions for installing this binary,
|
||||
// see "@cypress/commit-message-install"
|
||||
const env = {
|
||||
CYPRESS_INSTALL_BINARY: binary,
|
||||
}
|
||||
|
||||
const getStatusAndMessage = (projectRepoName) => {
|
||||
// also pass "status" object that points back at this repo and this commit
|
||||
// so that other projects can report their test success as GitHub commit status check
|
||||
let status = null
|
||||
const commit = commitInfo && commitInfo.sha
|
||||
|
||||
if (commit && is.commitId(commit)) {
|
||||
// commit is full 40 character hex string
|
||||
const platform = os.platform()
|
||||
const arch = os.arch()
|
||||
|
||||
status = {
|
||||
owner: 'cypress-io',
|
||||
repo: 'cypress',
|
||||
sha: commit,
|
||||
platform,
|
||||
arch,
|
||||
context: `[${platform}-${arch}] ${projectRepoName}`,
|
||||
}
|
||||
}
|
||||
|
||||
const commitMessageInstructions = getInstallJson({
|
||||
packages: npm,
|
||||
env,
|
||||
platform,
|
||||
arch,
|
||||
branch: shortNpmVersion, // use as version as branch name on test projects
|
||||
commit,
|
||||
status,
|
||||
})
|
||||
const jsonBlock = toMarkdownJsonBlock(commitMessageInstructions)
|
||||
const footer =
|
||||
'Use tool `@cypress/commit-message-install` to install from above block'
|
||||
let message = `${subject}\n\n${jsonBlock}\n${footer}\n`
|
||||
|
||||
if (process.env.CIRCLE_BUILD_URL) {
|
||||
message += '\n'
|
||||
message += stripIndent`
|
||||
CircleCI job url: ${process.env.CIRCLE_BUILD_URL}
|
||||
`
|
||||
}
|
||||
|
||||
console.log('commit message:')
|
||||
console.log(message)
|
||||
|
||||
return {
|
||||
status,
|
||||
message,
|
||||
}
|
||||
}
|
||||
|
||||
const onError = (e) => {
|
||||
console.error('could not bump test projects')
|
||||
console.error(e)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
bump
|
||||
.runTestProjects(
|
||||
getStatusAndMessage,
|
||||
cliOptions.provider,
|
||||
shortNpmVersion,
|
||||
platform,
|
||||
)
|
||||
.catch(onError)
|
||||
@@ -1,48 +0,0 @@
|
||||
const la = require('lazy-ass')
|
||||
const snapshot = require('snap-shot-it')
|
||||
const _ = require('lodash')
|
||||
|
||||
const bump = require('../../binary/bump')
|
||||
|
||||
/* eslint-env mocha */
|
||||
describe('bump', () => {
|
||||
context('remapProjects', () => {
|
||||
it('returns flat list of projects', () => {
|
||||
la(bump._PROVIDERS, 'has _PROVIDERS', bump)
|
||||
const list = bump.remapProjects(bump._PROVIDERS)
|
||||
|
||||
snapshot('list of all projects', list)
|
||||
})
|
||||
})
|
||||
|
||||
context('getFilterByProvider', () => {
|
||||
it('returns a filter function without provider name', () => {
|
||||
const projects = bump.remapProjects(bump._PROVIDERS)
|
||||
const filter = bump.getFilterByProvider()
|
||||
// should return ALL projects
|
||||
const filtered = projects.filter(filter)
|
||||
|
||||
la(
|
||||
_.isEqual(filtered, projects),
|
||||
'should have kept all projects',
|
||||
filtered,
|
||||
)
|
||||
})
|
||||
|
||||
it('returns a filter function for circle and linux', () => {
|
||||
const projects = bump.remapProjects(bump._PROVIDERS)
|
||||
|
||||
la(
|
||||
projects.length,
|
||||
'there should be at least a few projects in the list of projects',
|
||||
projects,
|
||||
)
|
||||
|
||||
const filter = bump.getFilterByProvider('circle', 'linux')
|
||||
const filtered = projects.filter(filter)
|
||||
|
||||
la(filtered.length, 'there should be at least a few projects', filtered)
|
||||
snapshot('should have just circle and linux projects', filtered)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -57,7 +57,12 @@ class DockerProcess extends EventEmitter implements SpawnerResult {
|
||||
|
||||
for (const k in opts.env) {
|
||||
// skip problematic env vars that we don't wanna preserve from `process.env`
|
||||
if (['DISPLAY', 'USER', 'HOME', 'USERNAME', 'PATH'].includes(k)) continue
|
||||
if (
|
||||
['DISPLAY', 'USER', 'HOME', 'USERNAME', 'PATH'].includes(k)
|
||||
|| k.startsWith('npm_')
|
||||
) {
|
||||
continue
|
||||
}
|
||||
|
||||
containerCreateEnv.push([k, opts.env[k]].join('='))
|
||||
}
|
||||
@@ -78,6 +83,7 @@ class DockerProcess extends EventEmitter implements SpawnerResult {
|
||||
Entrypoint: 'bash',
|
||||
Tty: false, // so we can use stdout and stderr
|
||||
Env: containerCreateEnv,
|
||||
Privileged: true,
|
||||
Binds: [
|
||||
[path.join(__dirname, '..', '..'), '/cypress'],
|
||||
// map tmpDir to the same absolute path on the container to make it easier to reason about paths in tests
|
||||
|
||||
12
system-tests/projects/module-api/.gitignore
vendored
Normal file
12
system-tests/projects/module-api/.gitignore
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
.DS_Store
|
||||
node_modules/
|
||||
cypress/videos/
|
||||
cypress/plugins/
|
||||
test/successful/cypress/videos/
|
||||
test/invalid/cypress/videos
|
||||
test/failing/cypress/videos
|
||||
test/failing/cypress/screenshots
|
||||
test/invalid/cypress/screenshots
|
||||
|
||||
test/env/cypress/videos
|
||||
test/env/cypress/screenshots
|
||||
5
system-tests/projects/module-api/README.md
Normal file
5
system-tests/projects/module-api/README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
Example and test running specs using [Cypress](https://www.cypress.io) via its [Module API](https://on.cypress.io/module-api)
|
||||
|
||||
## Debugging
|
||||
|
||||
Run tests with `DEBUG=test` environment variable to see more log messages
|
||||
15
system-tests/projects/module-api/async.js
Normal file
15
system-tests/projects/module-api/async.js
Normal file
@@ -0,0 +1,15 @@
|
||||
const cypress = require('cypress')
|
||||
|
||||
console.log('cypress is', cypress)
|
||||
|
||||
async function testSpec (spec) {
|
||||
console.assert(spec, 'missing spec filename')
|
||||
console.log('running test %s', spec)
|
||||
const result = await cypress.run({ spec })
|
||||
|
||||
console.log(result)
|
||||
}
|
||||
(async () => {
|
||||
await testSpec('./cypress/integration/a-spec.js')
|
||||
await testSpec('./cypress/integration/b-spec.js')
|
||||
})()
|
||||
4
system-tests/projects/module-api/cypress.json
Normal file
4
system-tests/projects/module-api/cypress.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"pluginsFile": false,
|
||||
"supportFile": false
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
describe('cypress example - a-spec', () => {
|
||||
it('works', () => {
|
||||
expect(true).to.be.true
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,5 @@
|
||||
describe('cypress example - b-spec', () => {
|
||||
it('works', () => {
|
||||
expect(true).to.be.true
|
||||
})
|
||||
})
|
||||
20
system-tests/projects/module-api/index.js
Normal file
20
system-tests/projects/module-api/index.js
Normal file
@@ -0,0 +1,20 @@
|
||||
const banner = require('terminal-banner').terminalBanner
|
||||
const allPaths = require('@bahmutov/all-paths')
|
||||
const cypress = require('cypress')
|
||||
|
||||
console.log('cypress is', cypress)
|
||||
|
||||
const onSuccess = (runResult) => {
|
||||
banner('Cypresss results')
|
||||
console.log('%o', runResult)
|
||||
banner('Results paths')
|
||||
// TODO find a better way to show all available properties in the runResult object
|
||||
// maybe a tree representation in the terminal?
|
||||
console.log(allPaths(runResult).join('\n'))
|
||||
}
|
||||
|
||||
cypress.run({
|
||||
spec: './cypress/integration/a-spec.js',
|
||||
})
|
||||
.then(onSuccess)
|
||||
.catch(console.error)
|
||||
22
system-tests/projects/module-api/package.json
Normal file
22
system-tests/projects/module-api/package.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "@test-project/cypress-example-module-api",
|
||||
"version": "0.0.0-development",
|
||||
"description": "Example running specs using Cypress via its module API",
|
||||
"private": true,
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "mocha --timeout 30000 test/spec.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@bahmutov/all-paths": "1.0.2",
|
||||
"chdir-promise": "0.6.2",
|
||||
"check-more-types": "2.24.0",
|
||||
"debug": "4.3.3",
|
||||
"lazy-ass": "1.6.0",
|
||||
"mocha": "9.2.0",
|
||||
"mocha-banner": "1.1.2",
|
||||
"ramda": "0.28.0",
|
||||
"snap-shot-it": "5.0.1",
|
||||
"terminal-banner": "1.1.0"
|
||||
}
|
||||
}
|
||||
4
system-tests/projects/module-api/test/env/cypress.json
vendored
Normal file
4
system-tests/projects/module-api/test/env/cypress.json
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"pluginsFile": false,
|
||||
"supportFile": false
|
||||
}
|
||||
11
system-tests/projects/module-api/test/env/cypress/integration/env-spec.js
vendored
Normal file
11
system-tests/projects/module-api/test/env/cypress/integration/env-spec.js
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
/// <reference types="cypress" />
|
||||
it('has expected env variables', () => {
|
||||
// this test checks environment variables
|
||||
// passed via "cypress.run" arguments
|
||||
cy.wrap(Cypress.env()).should('deep.include', {
|
||||
foo: {
|
||||
bar: 'baz',
|
||||
},
|
||||
another: 42,
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,15 @@
|
||||
exports['failing test returns correct number of failing tests 1'] = {
|
||||
"cypressVersion": "0.0.0",
|
||||
"totalDuration": "X seconds",
|
||||
"totalSuites": 2,
|
||||
"totalTests": 2,
|
||||
"totalFailed": 1,
|
||||
"totalPassed": 1,
|
||||
"totalPending": 0,
|
||||
"totalSkipped": 0,
|
||||
"browserName": "electron",
|
||||
"browserVersion": "1.2.3",
|
||||
"osName": "darwin",
|
||||
"osVersion": "16.7.0"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"pluginsFile": false,
|
||||
"supportFile": false
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
describe('cypress example - a-spec', () => {
|
||||
it('this fails on purpose', () => {
|
||||
expect(false).to.be.true
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,5 @@
|
||||
describe('cypress example - b-spec', () => {
|
||||
it('works', () => {
|
||||
expect(true).to.be.true
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,15 @@
|
||||
exports['invalid malformed spec file returns with error code 1'] = {
|
||||
"cypressVersion": "0.0.0",
|
||||
"totalDuration": "X seconds",
|
||||
"totalSuites": 0,
|
||||
"totalTests": 1,
|
||||
"totalFailed": 1,
|
||||
"totalPassed": 0,
|
||||
"totalPending": 0,
|
||||
"totalSkipped": 0,
|
||||
"browserName": "electron",
|
||||
"browserVersion": "1.2.3",
|
||||
"osName": "darwin",
|
||||
"osVersion": "16.7.0"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"pluginsFile": false,
|
||||
"supportFile": false
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// this spec file is invalid on purpose
|
||||
// to see how Cypress detects "bad" spec file
|
||||
// eslint-disable-next-line no-undef
|
||||
foobar()
|
||||
@@ -0,0 +1,5 @@
|
||||
describe('cypress example - b-spec', () => {
|
||||
it('works', () => {
|
||||
expect(true).to.be.true
|
||||
})
|
||||
})
|
||||
158
system-tests/projects/module-api/test/spec.js
Normal file
158
system-tests/projects/module-api/test/spec.js
Normal file
@@ -0,0 +1,158 @@
|
||||
require('mocha-banner').register()
|
||||
|
||||
const cypress = require('cypress')
|
||||
const chdir = require('chdir-promise')
|
||||
const join = require('path').join
|
||||
const fromFolder = join.bind(null, __dirname)
|
||||
const snapshot = require('snap-shot-it')
|
||||
const la = require('lazy-ass')
|
||||
const is = require('check-more-types')
|
||||
const debug = require('debug')('test')
|
||||
const R = require('ramda')
|
||||
|
||||
const importantProperties = [
|
||||
'cypressVersion',
|
||||
'totalDuration',
|
||||
'totalSuites',
|
||||
'totalTests',
|
||||
'totalFailed',
|
||||
'totalPassed',
|
||||
'totalPending',
|
||||
'totalSkipped',
|
||||
'browserName',
|
||||
'browserVersion',
|
||||
'osName',
|
||||
'osVersion',
|
||||
]
|
||||
|
||||
const pickImportant = R.pick(importantProperties)
|
||||
|
||||
const normalize = (output) => {
|
||||
la(is.unemptyString(output.cypressVersion), 'has Cypress version', output)
|
||||
la(is.positive(output.totalDuration), 'has duration', output)
|
||||
la(is.unemptyString(output.browserVersion), 'has browserVersion', output)
|
||||
la(is.unemptyString(output.osName), 'has osName', output)
|
||||
la(is.unemptyString(output.osVersion), 'has osVersion', output)
|
||||
|
||||
output.cypressVersion = '0.0.0'
|
||||
output.totalDuration = 'X seconds'
|
||||
output.browserVersion = '1.2.3'
|
||||
output.osName = 'darwin'
|
||||
output.osVersion = '16.7.0'
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
describe('successful tests', () => {
|
||||
const projectFolder = fromFolder('successful')
|
||||
|
||||
beforeEach(() => {
|
||||
chdir.to(projectFolder)
|
||||
})
|
||||
|
||||
afterEach(chdir.back)
|
||||
|
||||
it('returns with all successful tests', () => {
|
||||
return cypress.run()
|
||||
.then(R.tap(debug))
|
||||
.then(normalize)
|
||||
.then(pickImportant)
|
||||
.then(snapshot)
|
||||
})
|
||||
|
||||
it('runs specific spec', () => {
|
||||
return cypress.run({
|
||||
spec: 'cypress/integration/a-spec.js',
|
||||
}).then(R.tap(debug))
|
||||
.then((result) => {
|
||||
la(result.totalTests === 1, 'there should be single test', result.totalTests)
|
||||
})
|
||||
})
|
||||
|
||||
it('runs specific spec using absolute path', () => {
|
||||
const absoluteSpec = join(projectFolder, 'cypress/integration/a-spec.js')
|
||||
|
||||
debug('absolute path to the spec: %s', absoluteSpec)
|
||||
|
||||
return cypress.run({
|
||||
spec: absoluteSpec,
|
||||
}).then(R.tap(debug))
|
||||
.then((result) => {
|
||||
la(result.totalTests === 1, 'there should be single test', result.totalTests)
|
||||
})
|
||||
})
|
||||
|
||||
it('runs a single spec using wildcard', () => {
|
||||
return cypress.run({
|
||||
spec: 'cypress/integration/a-*.js',
|
||||
}).then(R.tap(debug))
|
||||
.then((result) => {
|
||||
la(result.totalTests === 1, 'there should be single test', result.totalTests)
|
||||
})
|
||||
})
|
||||
|
||||
it('runs both found specs using wildcard', () => {
|
||||
return cypress.run({
|
||||
spec: 'cypress/integration/a-*.js,cypress/integration/b-*.js',
|
||||
}).then(R.tap(debug))
|
||||
.then((result) => {
|
||||
la(result.totalTests === 2, 'found both tests', result.totalTests)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('env variables', () => {
|
||||
const projectFolder = fromFolder('env')
|
||||
|
||||
beforeEach(() => {
|
||||
chdir.to(projectFolder)
|
||||
})
|
||||
|
||||
afterEach(chdir.back)
|
||||
|
||||
it('passes environment variables in the object', () => {
|
||||
return cypress.run({
|
||||
spec: 'cypress/integration/env-spec.js',
|
||||
env: {
|
||||
foo: {
|
||||
bar: 'baz',
|
||||
},
|
||||
another: 42,
|
||||
},
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('failing test', () => {
|
||||
beforeEach(() => {
|
||||
chdir.to(fromFolder('failing'))
|
||||
})
|
||||
|
||||
afterEach(chdir.back)
|
||||
|
||||
it('returns correct number of failing tests', () => {
|
||||
return cypress.run()
|
||||
.then(normalize)
|
||||
.then(pickImportant)
|
||||
.then(snapshot)
|
||||
})
|
||||
})
|
||||
|
||||
// https://github.com/cypress-io/cypress-test-module-api/issues/3
|
||||
describe('invalid malformed spec file', () => {
|
||||
beforeEach(() => {
|
||||
chdir.to(fromFolder('invalid'))
|
||||
})
|
||||
|
||||
afterEach(chdir.back)
|
||||
|
||||
it('returns with error code', () => {
|
||||
// test has reference error on load
|
||||
return cypress.run({
|
||||
spec: './cypress/integration/a-spec.js',
|
||||
})
|
||||
.then(normalize)
|
||||
.then(pickImportant)
|
||||
.then(snapshot)
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,15 @@
|
||||
exports['successful tests returns with all successful tests 1'] = {
|
||||
"cypressVersion": "0.0.0",
|
||||
"totalDuration": "X seconds",
|
||||
"totalSuites": 2,
|
||||
"totalTests": 2,
|
||||
"totalFailed": 0,
|
||||
"totalPassed": 2,
|
||||
"totalPending": 0,
|
||||
"totalSkipped": 0,
|
||||
"browserName": "electron",
|
||||
"browserVersion": "1.2.3",
|
||||
"osName": "darwin",
|
||||
"osVersion": "16.7.0"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"pluginsFile": false,
|
||||
"supportFile": false
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
describe('cypress example - a-spec', () => {
|
||||
it('works', () => {
|
||||
expect(true).to.be.true
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,5 @@
|
||||
describe('cypress example - b-spec', () => {
|
||||
it('works', () => {
|
||||
expect(true).to.be.true
|
||||
})
|
||||
})
|
||||
815
system-tests/projects/module-api/yarn.lock
Normal file
815
system-tests/projects/module-api/yarn.lock
Normal file
@@ -0,0 +1,815 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@bahmutov/all-paths@1.0.2":
|
||||
version "1.0.2"
|
||||
resolved "https://registry.npmjs.org/@bahmutov/all-paths/-/all-paths-1.0.2.tgz#9ae0dcdf9022dd6e5e14d7fda3479e6a330d035b"
|
||||
integrity "sha1-muDc35Ai3W5eFNf9o0eeajMNA1s= sha512-kqeMYh7e9yXWSm7LdQp4BZ4Igxk25lM2Jtw4+G83ro5nFvbHAp3ZmY2na/AVk57+CpZDH/sCXxyKFwkdisnkbw=="
|
||||
dependencies:
|
||||
lodash.isplainobject "4.0.6"
|
||||
lodash.range "3.2.0"
|
||||
|
||||
"@bahmutov/data-driven@1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.npmjs.org/@bahmutov/data-driven/-/data-driven-1.0.0.tgz#6897061cd61a0afc26a7079527bfbb1073b4228a"
|
||||
integrity "sha1-aJcGHNYaCvwmpweVJ7+7EHO0Ioo= sha512-YqW3hPS0RXriqjcCrLOTJj+LWe3c8JpwlL83k1ka1Q8U05ZjAKbGQZYeTzUd0NFEnnfPtsUiKGpFEBJG6kFuvg=="
|
||||
dependencies:
|
||||
check-more-types "2.24.0"
|
||||
lazy-ass "1.6.0"
|
||||
|
||||
"@ungap/promise-all-settled@1.1.2":
|
||||
version "1.1.2"
|
||||
resolved "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44"
|
||||
integrity "sha1-qlgEJxHW4ydd033Fl+XTHowpCkQ= sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q=="
|
||||
|
||||
ansi-colors@4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348"
|
||||
integrity "sha1-y7muJWv3UK8eqzRPIpqif+lLo0g= sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA=="
|
||||
|
||||
ansi-regex@^2.0.0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
|
||||
integrity "sha1-w7M6te42DYbg5ijwRorn7yfWVN8= sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA=="
|
||||
|
||||
ansi-regex@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
|
||||
integrity "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= sha512-wFUFA5bg5dviipbQQ32yOQhl6gcJaJXiHE7dvR8VYPG97+J/GNC5FKGepKdEDUFeXRzDxPF1X/Btc8L+v7oqIQ=="
|
||||
|
||||
ansi-regex@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
|
||||
integrity "sha1-CCyyyJyf6GWaMRpTvWpNxTAdswQ= sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
|
||||
|
||||
ansi-styles@^2.0.1, ansi-styles@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
|
||||
integrity "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA=="
|
||||
|
||||
ansi-styles@^4.0.0, ansi-styles@^4.1.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
|
||||
integrity "sha1-7dgDYornHATIWuegkG7a00tkiTc= sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="
|
||||
dependencies:
|
||||
color-convert "^2.0.1"
|
||||
|
||||
anymatch@~3.1.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716"
|
||||
integrity "sha1-wFV8CWrzLxBhmPT04qODU343hxY= sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg=="
|
||||
dependencies:
|
||||
normalize-path "^3.0.0"
|
||||
picomatch "^2.0.4"
|
||||
|
||||
argparse@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
|
||||
integrity "sha1-JG9Q88p4oyQPbJl+ipvR6sSeSzg= sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
||||
|
||||
balanced-match@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
||||
integrity "sha1-6D46fj8wCzTLnYf2FfoMvzV2kO4= sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||
|
||||
binary-extensions@^2.0.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
|
||||
integrity "sha1-dfUC7q+f/eQvyYgpZFvk6na9ni0= sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA=="
|
||||
|
||||
bluebird@^3.5.1:
|
||||
version "3.7.2"
|
||||
resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
|
||||
integrity "sha1-nyKcFb4nJFT/qXOs4NvueaGww28= sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
|
||||
|
||||
brace-expansion@^1.1.7:
|
||||
version "1.1.11"
|
||||
resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
||||
integrity "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0= sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="
|
||||
dependencies:
|
||||
balanced-match "^1.0.0"
|
||||
concat-map "0.0.1"
|
||||
|
||||
braces@~3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
|
||||
integrity "sha1-NFThpGLujVmeI23zNs2epPiv4Qc= sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A=="
|
||||
dependencies:
|
||||
fill-range "^7.0.1"
|
||||
|
||||
browser-stdout@1.3.1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60"
|
||||
integrity "sha1-uqVZ7hTO1zRSIputcyZGfGH6vWA= sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw=="
|
||||
|
||||
camelcase@^6.0.0:
|
||||
version "6.3.0"
|
||||
resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a"
|
||||
integrity "sha1-VoW5XrIJrJwMF3Rnd4ychN9Yupo= sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA=="
|
||||
|
||||
chalk@^1.1.1:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
|
||||
integrity "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A=="
|
||||
dependencies:
|
||||
ansi-styles "^2.2.1"
|
||||
escape-string-regexp "^1.0.2"
|
||||
has-ansi "^2.0.0"
|
||||
strip-ansi "^3.0.0"
|
||||
supports-color "^2.0.0"
|
||||
|
||||
chalk@^4.1.0:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
|
||||
integrity "sha1-qsTit3NKdAhnrrFr8CqtVWoeegE= sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="
|
||||
dependencies:
|
||||
ansi-styles "^4.1.0"
|
||||
supports-color "^7.1.0"
|
||||
|
||||
chdir-promise@0.6.2:
|
||||
version "0.6.2"
|
||||
resolved "https://registry.npmjs.org/chdir-promise/-/chdir-promise-0.6.2.tgz#d4cfa0a96a112a8149341b69e2866d162f0e2dbd"
|
||||
integrity "sha1-1M+gqWoRKoFJNBtp4oZtFi8OLb0= sha512-EG5MutQt4qTxoQPfBtPCfU1A/MqborgaO66xrPSD/dRTB40OLN0wy+YAo5ZAw7DawhtCPdZHAdQ206fyWkhoiw=="
|
||||
dependencies:
|
||||
bluebird "^3.5.1"
|
||||
check-more-types "2.24.0"
|
||||
debug "3.1.0"
|
||||
lazy-ass "1.6.0"
|
||||
|
||||
check-more-types@2.24.0:
|
||||
version "2.24.0"
|
||||
resolved "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600"
|
||||
integrity "sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA= sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA=="
|
||||
|
||||
chokidar@3.5.3:
|
||||
version "3.5.3"
|
||||
resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
|
||||
integrity "sha1-HPN8hwe5Mr0a8a4iwEMuKs0ZA70= sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw=="
|
||||
dependencies:
|
||||
anymatch "~3.1.2"
|
||||
braces "~3.0.2"
|
||||
glob-parent "~5.1.2"
|
||||
is-binary-path "~2.1.0"
|
||||
is-glob "~4.0.1"
|
||||
normalize-path "~3.0.0"
|
||||
readdirp "~3.6.0"
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
ci-info@^1.0.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497"
|
||||
integrity "sha1-LKINu5zrMtRSSmgzAzE/AwSx5Jc= sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A=="
|
||||
|
||||
cliui@^7.0.2:
|
||||
version "7.0.4"
|
||||
resolved "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f"
|
||||
integrity "sha1-oCZe5lVHb8gHrqnfPfjfd4OAi08= sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ=="
|
||||
dependencies:
|
||||
string-width "^4.2.0"
|
||||
strip-ansi "^6.0.0"
|
||||
wrap-ansi "^7.0.0"
|
||||
|
||||
color-convert@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
|
||||
integrity "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM= sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="
|
||||
dependencies:
|
||||
color-name "~1.1.4"
|
||||
|
||||
color-name@~1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
||||
integrity "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI= sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
|
||||
common-tags@1.8.0:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937"
|
||||
integrity "sha1-jjFT5ULUo56bEFVENK+q+YlWqTc= sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw=="
|
||||
|
||||
concat-map@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||
integrity "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
||||
|
||||
debug@3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
|
||||
integrity "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE= sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g=="
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
debug@4.3.3:
|
||||
version "4.3.3"
|
||||
resolved "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664"
|
||||
integrity "sha1-BCZuC3CpjURi5uKI44JZITMytmQ= sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q=="
|
||||
dependencies:
|
||||
ms "2.1.2"
|
||||
|
||||
decamelize@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837"
|
||||
integrity "sha1-qkcte/Zg6xXzSU79UxyrfypwmDc= sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ=="
|
||||
|
||||
diff@5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b"
|
||||
integrity "sha1-ftatdthZ0DB4fsNYVfWx2vMdhSs= sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w=="
|
||||
|
||||
diff@^1.3.2:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz#7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf"
|
||||
integrity "sha1-fyjS657nsVqX79ic5j3P2qPMur8= sha512-VzVc42hMZbYU9Sx/ltb7KYuQ6pqAw+cbFWVy4XKdkuEL2CFaRLGEnISPs7YdzaUGpi+CpIqvRmu7hPQ4T7EQ5w=="
|
||||
|
||||
disparity@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/disparity/-/disparity-2.0.0.tgz#57ddacb47324ae5f58d2cc0da886db4ce9eeb718"
|
||||
integrity "sha1-V92stHMkrl9Y0swNqIbbTOnutxg= sha512-caMA9oIQbDeobWc9MVUF0+o1APVo0UZnfD482x0RaLLAzpAc6Dla2mk5ef7onsG91tziIRr41rj4sVt3BOLLZw=="
|
||||
dependencies:
|
||||
ansi-styles "^2.0.1"
|
||||
diff "^1.3.2"
|
||||
|
||||
emoji-regex@^8.0.0:
|
||||
version "8.0.0"
|
||||
resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
|
||||
integrity "sha1-6Bj9ac5cz8tARZT4QpY79TFkzDc= sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
|
||||
escalade@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
|
||||
integrity "sha1-2M/ccACWXFoBdLSoLqpcBVJ0LkA= sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw=="
|
||||
|
||||
escape-quotes@1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.npmjs.org/escape-quotes/-/escape-quotes-1.0.2.tgz#b4896d4a6cf82dd5b33f49b713408c6380f6cd97"
|
||||
integrity "sha1-tIltSmz4LdWzP0m3E0CMY4D2zZc= sha512-JpLFzklNReeakCpyj59s78P5F72q0ZUpDnp2BuIk9TtTjj2HMsgiWBChw17BlZT8dRhMtmSb1jE2+pTP1iFYyw=="
|
||||
dependencies:
|
||||
escape-string-regexp "^1.0.5"
|
||||
|
||||
escape-string-regexp@4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
|
||||
integrity "sha1-FLqDpdNz49MR5a/KKc9b+tllvzQ= sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="
|
||||
|
||||
escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
||||
integrity "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="
|
||||
|
||||
fill-range@^7.0.1:
|
||||
version "7.0.1"
|
||||
resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
|
||||
integrity "sha1-GRmmp8df44ssfHflGYU12prN2kA= sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ=="
|
||||
dependencies:
|
||||
to-regex-range "^5.0.1"
|
||||
|
||||
find-up@5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc"
|
||||
integrity "sha1-TJKBnstwg1YeT0okCoa+UZj1Nvw= sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="
|
||||
dependencies:
|
||||
locate-path "^6.0.0"
|
||||
path-exists "^4.0.0"
|
||||
|
||||
flat@^5.0.2:
|
||||
version "5.0.2"
|
||||
resolved "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241"
|
||||
integrity "sha1-jKb+MyBp/6nTJMMnGYxZglnOskE= sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ=="
|
||||
|
||||
folktale@2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.npmjs.org/folktale/-/folktale-2.0.1.tgz#6dc26a65565aefdef9520223e022dddf5b8d8462"
|
||||
integrity "sha1-bcJqZVZa7975UgIj4CLd31uNhGI= sha512-3kDSWVkSlErHIt/dC73vu+5zRqbW1mlnL46s2QfYN7Ps0JcS9MVtuLCrDQOBa7sanA+d9Fd8F+bn0VcyNe68Jw=="
|
||||
|
||||
folktale@2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.npmjs.org/folktale/-/folktale-2.1.0.tgz#3332b9e37b4b92150788b72bd0e2ddd8d70e4096"
|
||||
integrity "sha1-MzK543tLkhUHiLcr0OLd2NcOQJY= sha512-eG9lWx/MAOPoFllqASH7d1+QMl6qCd+E+rOPSWgulFPKG55506kXKQZLnMg3fMHFZUWY/2POZUPc/MH7048nIg=="
|
||||
|
||||
fs.realpath@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||
integrity "sha1-FQStJSMVjKpA20onh8sBQRmU6k8= sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
|
||||
|
||||
fsevents@~2.3.2:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
|
||||
integrity "sha1-ilJveLj99GI7cJ4Ll1xSwkwC/Ro= sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="
|
||||
|
||||
get-caller-file@^2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
|
||||
integrity "sha1-T5RBKoLbMvNuOwuXQfipf+sDH34= sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
|
||||
|
||||
glob-parent@~5.1.2:
|
||||
version "5.1.2"
|
||||
resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
|
||||
integrity "sha1-hpgyxYA0/mikCTwX3BXoNA2EAcQ= sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="
|
||||
dependencies:
|
||||
is-glob "^4.0.1"
|
||||
|
||||
glob@7.2.0:
|
||||
version "7.2.0"
|
||||
resolved "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023"
|
||||
integrity "sha1-0VU1r3cy4C6Uj0xBYovZECk/YCM= sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q=="
|
||||
dependencies:
|
||||
fs.realpath "^1.0.0"
|
||||
inflight "^1.0.4"
|
||||
inherits "2"
|
||||
minimatch "^3.0.4"
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
growl@1.10.5:
|
||||
version "1.10.5"
|
||||
resolved "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e"
|
||||
integrity "sha1-8nNdwig2dPpnR4sQGBBZNVw2nl4= sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA=="
|
||||
|
||||
has-ansi@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
|
||||
integrity "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg=="
|
||||
dependencies:
|
||||
ansi-regex "^2.0.0"
|
||||
|
||||
has-flag@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
|
||||
integrity "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s= sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
|
||||
|
||||
has-only@1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.npmjs.org/has-only/-/has-only-1.1.1.tgz#0ed2b101e73a2226254421464c65e381affcce66"
|
||||
integrity "sha1-DtKxAec6IiYlRCFGTGXjga/8zmY= sha512-3GuFy9rDw0xvovCHb4SOKiRImbZ+a8boFBUyGNRPVd2mRyQOzYdau5G9nodUXC1ZKYN59hrHFkW1lgBQscYfTg=="
|
||||
|
||||
he@1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
|
||||
integrity "sha1-hK5l+n6vsWX922FWauFLrwVmTw8= sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="
|
||||
|
||||
inflight@^1.0.4:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
|
||||
integrity "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA=="
|
||||
dependencies:
|
||||
once "^1.3.0"
|
||||
wrappy "1"
|
||||
|
||||
inherits@2:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w= sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
|
||||
is-binary-path@~2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
|
||||
integrity "sha1-6h9/O4DwZCNug0cPhsCcJU+0Wwk= sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw=="
|
||||
dependencies:
|
||||
binary-extensions "^2.0.0"
|
||||
|
||||
is-ci@1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.npmjs.org/is-ci/-/is-ci-1.1.0.tgz#247e4162e7860cebbdaf30b774d6b0ac7dcfe7a5"
|
||||
integrity "sha1-JH5BYueGDOu9rzC3dNawrH3P56U= sha512-c7TnwxLePuqIlxHgr7xtxzycJPegNHFuIrBkwbf8hc58//+Op1CqFkyS+xnIMkwn9UsJIwc174BIjkyBmSpjKg=="
|
||||
dependencies:
|
||||
ci-info "^1.0.0"
|
||||
|
||||
is-extglob@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
|
||||
integrity "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="
|
||||
|
||||
is-fullwidth-code-point@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
|
||||
integrity "sha1-8Rb4Bk/pCz94RKOJl8C3UFEmnx0= sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
|
||||
|
||||
is-glob@^4.0.1, is-glob@~4.0.1:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
|
||||
integrity "sha1-ZPYeQsu7LuwgcanawLKLoeZdUIQ= sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="
|
||||
dependencies:
|
||||
is-extglob "^2.1.1"
|
||||
|
||||
is-number@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
|
||||
integrity "sha1-dTU0W4lnNNX4DE0GxQlVUnoU8Ss= sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
|
||||
|
||||
is-plain-obj@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287"
|
||||
integrity "sha1-ReQuN/zPH0Dajl927iFRWEDAkoc= sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA=="
|
||||
|
||||
is-unicode-supported@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7"
|
||||
integrity "sha1-PybHaoCVk7Ur+i7LVxDtJ3m1Iqc= sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw=="
|
||||
|
||||
isexe@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
|
||||
integrity "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
|
||||
|
||||
its-name@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.npmjs.org/its-name/-/its-name-1.0.0.tgz#2065f1883ecb568c65f7112ddbf123401fae4af0"
|
||||
integrity "sha1-IGXxiD7LVoxl9xEt2/EjQB+uSvA= sha512-GYUWFxViqxDvGzsNEItTEuOqqAQVx29Xl9Lh5YUqyJd6gPHTCMiIbjqcjjyUzsBUqEcgwIdRoydwgfFw1oYbhg=="
|
||||
|
||||
js-yaml@4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
|
||||
integrity "sha1-wftl+PUBeQHN0slRhkuhhFihBgI= sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="
|
||||
dependencies:
|
||||
argparse "^2.0.1"
|
||||
|
||||
jsesc@2.5.1:
|
||||
version "2.5.1"
|
||||
resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.1.tgz#e421a2a8e20d6b0819df28908f782526b96dd1fe"
|
||||
integrity "sha1-5CGiqOINawgZ3yiQj3glJrlt0f4= sha512-Bl0oKW/TMSVifAQLbupbpOrssQ3CC+lyhZZjofI19OuKtwq8/A9KtxDA22wppbeiFqAQdTnVkDR8ymtRFAxtYw=="
|
||||
|
||||
lazy-ass@1.6.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz#7999655e8646c17f089fdd187d150d3324d54513"
|
||||
integrity "sha1-eZllXoZGwX8In90YfRUNMyTVRRM= sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw=="
|
||||
|
||||
locate-path@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286"
|
||||
integrity "sha1-VTIeswn+u8WcSAHZMackUqaB0oY= sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="
|
||||
dependencies:
|
||||
p-locate "^5.0.0"
|
||||
|
||||
lodash.isplainobject@4.0.6:
|
||||
version "4.0.6"
|
||||
resolved "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
|
||||
integrity "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs= sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="
|
||||
|
||||
lodash.range@3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.npmjs.org/lodash.range/-/lodash.range-3.2.0.tgz#f461e588f66683f7eadeade513e38a69a565a15d"
|
||||
integrity "sha1-9GHliPZmg/fq3q3lE+OKaaVloV0= sha512-Fgkb7SinmuzqgIhNhAElo0BL/R1rHCnhwSZf78omqSwvWqD0kD2ssOAutQonDKH/ldS8BxA72ORYI09qAY9CYg=="
|
||||
|
||||
log-symbols@4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503"
|
||||
integrity "sha1-P727lbRoOsn8eFER55LlWNSr1QM= sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg=="
|
||||
dependencies:
|
||||
chalk "^4.1.0"
|
||||
is-unicode-supported "^0.1.0"
|
||||
|
||||
minimatch@3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
||||
integrity "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM= sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA=="
|
||||
dependencies:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
minimatch@^3.0.4:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
|
||||
integrity "sha1-Gc0ZS/0+Qo8EmnCBfAONiatL41s= sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="
|
||||
dependencies:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
minimist@0.0.8:
|
||||
version "0.0.8"
|
||||
resolved "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
|
||||
integrity "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= sha512-miQKw5Hv4NS1Psg2517mV4e4dYNaO3++hjAvLOAzKqZ61rH8NS1SK+vbfBWZ5PY/Me/bEWhUwqMghEW5Fb9T7Q=="
|
||||
|
||||
mkdirp@0.5.1:
|
||||
version "0.5.1"
|
||||
resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
|
||||
integrity "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= sha512-SknJC52obPfGQPnjIkXbmA6+5H15E+fR+E4iR2oQ3zzCLbd7/ONua69R/Gw7AgkTLsRG+r5fzksYwWe1AgTyWA=="
|
||||
dependencies:
|
||||
minimist "0.0.8"
|
||||
|
||||
mocha-banner@1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.npmjs.org/mocha-banner/-/mocha-banner-1.1.2.tgz#7cac0e35daf805dfe2adb6d8158cab1085bdf6a4"
|
||||
integrity "sha1-fKwONdr4Bd/irbbYFYyrEIW99qQ= sha512-dsAEp32v2vmPM7CP7cmdDLjcWIohoSPV2bTOltyE0Bb8A1raVCSsLMBJlWpr/+lDoVlrPwwsM1SNCYqeyznFeQ=="
|
||||
dependencies:
|
||||
its-name "1.0.0"
|
||||
terminal-banner "1.1.0"
|
||||
|
||||
mocha@9.2.0:
|
||||
version "9.2.0"
|
||||
resolved "https://registry.npmjs.org/mocha/-/mocha-9.2.0.tgz#2bfba73d46e392901f877ab9a47b7c9c5d0275cc"
|
||||
integrity "sha1-K/unPUbjkpAfh3q5pHt8nF0Cdcw= sha512-kNn7E8g2SzVcq0a77dkphPsDSN7P+iYkqE0ZsGCYWRsoiKjOt+NvXfaagik8vuDa6W5Zw3qxe8Jfpt5qKf+6/Q=="
|
||||
dependencies:
|
||||
"@ungap/promise-all-settled" "1.1.2"
|
||||
ansi-colors "4.1.1"
|
||||
browser-stdout "1.3.1"
|
||||
chokidar "3.5.3"
|
||||
debug "4.3.3"
|
||||
diff "5.0.0"
|
||||
escape-string-regexp "4.0.0"
|
||||
find-up "5.0.0"
|
||||
glob "7.2.0"
|
||||
growl "1.10.5"
|
||||
he "1.2.0"
|
||||
js-yaml "4.1.0"
|
||||
log-symbols "4.1.0"
|
||||
minimatch "3.0.4"
|
||||
ms "2.1.3"
|
||||
nanoid "3.2.0"
|
||||
serialize-javascript "6.0.0"
|
||||
strip-json-comments "3.1.1"
|
||||
supports-color "8.1.1"
|
||||
which "2.0.2"
|
||||
workerpool "6.2.0"
|
||||
yargs "16.2.0"
|
||||
yargs-parser "20.2.4"
|
||||
yargs-unparser "2.0.0"
|
||||
|
||||
ms@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||
integrity "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
|
||||
|
||||
ms@2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
||||
integrity "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk= sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
|
||||
ms@2.1.3:
|
||||
version "2.1.3"
|
||||
resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
||||
integrity "sha1-V0yBOM4dK1hh8LRFedut1gxmFbI= sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||
|
||||
nanoid@3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c"
|
||||
integrity "sha1-YmZ1Itpmc5ccypFqbT7/P0Ff+Aw= sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA=="
|
||||
|
||||
normalize-path@^3.0.0, normalize-path@~3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
|
||||
integrity "sha1-Dc1p/yOhybEf0JeDFmRKA4ghamU= sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
|
||||
|
||||
object-assign@^4.0.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
integrity "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="
|
||||
|
||||
once@^1.3.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
||||
integrity "sha1-WDsap3WWHUsROsF9nFC6753Xa9E= sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="
|
||||
dependencies:
|
||||
wrappy "1"
|
||||
|
||||
p-limit@^3.0.2:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b"
|
||||
integrity "sha1-4drMvnjQ0TiMoYxk/qOOPlfjcGs= sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="
|
||||
dependencies:
|
||||
yocto-queue "^0.1.0"
|
||||
|
||||
p-locate@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834"
|
||||
integrity "sha1-g8gxXGeFAF470CGDlBHJ4RDm2DQ= sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="
|
||||
dependencies:
|
||||
p-limit "^3.0.2"
|
||||
|
||||
path-exists@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
|
||||
integrity "sha1-UTvb4tO5XXdi6METfvoZXGxhtbM= sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="
|
||||
|
||||
path-is-absolute@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
||||
integrity "sha1-F0uSaHNVNP+8es5r9TpanhtcX18= sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="
|
||||
|
||||
picomatch@^2.0.4, picomatch@^2.2.1:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
|
||||
integrity "sha1-O6ODNzNkbZ0+SZWUbBNlpn+wekI= sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="
|
||||
|
||||
ramda@0.25.0:
|
||||
version "0.25.0"
|
||||
resolved "https://registry.npmjs.org/ramda/-/ramda-0.25.0.tgz#8fdf68231cffa90bc2f9460390a0cb74a29b29a9"
|
||||
integrity "sha1-j99oIxz/qQvC+UYDkKDLdKKbKak= sha512-GXpfrYVPwx3K7RQ6aYT8KPS8XViSXUVJT1ONhoKPE9VAleW42YE+U+8VEyGWt41EnEQW7gwecYJriTI0pKoecQ=="
|
||||
|
||||
ramda@0.28.0:
|
||||
version "0.28.0"
|
||||
resolved "https://registry.npmjs.org/ramda/-/ramda-0.28.0.tgz#acd785690100337e8b063cab3470019be427cc97"
|
||||
integrity "sha1-rNeFaQEAM36LBjyrNHABm+QnzJc= sha512-9QnLuG/kPVgWvMQ4aODhsBUFKOUmnbUnsSXACv+NCQZcHbeb+v8Lodp8OVxtRULN1/xOyYLLaL6npE6dMq5QTA=="
|
||||
|
||||
randombytes@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
|
||||
integrity "sha1-32+ENy8CcNxlzfYpE0mrekc9Tyo= sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ=="
|
||||
dependencies:
|
||||
safe-buffer "^5.1.0"
|
||||
|
||||
readdirp@~3.6.0:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
|
||||
integrity "sha1-dKNwvYVxFuJFspzJc0DNQxoCpsc= sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="
|
||||
dependencies:
|
||||
picomatch "^2.2.1"
|
||||
|
||||
require-directory@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
|
||||
integrity "sha1-jGStX9MNqxyXbiNE/+f3kqam30I= sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="
|
||||
|
||||
safe-buffer@^5.1.0:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
||||
integrity "sha1-Hq+fqb2x/dTsdfWPnNtOa3gn7sY= sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
|
||||
|
||||
serialize-javascript@6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8"
|
||||
integrity "sha1-765diPRdeSQUHai1w6en5mP+/rg= sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag=="
|
||||
dependencies:
|
||||
randombytes "^2.1.0"
|
||||
|
||||
snap-shot-compare@2.7.1:
|
||||
version "2.7.1"
|
||||
resolved "https://registry.npmjs.org/snap-shot-compare/-/snap-shot-compare-2.7.1.tgz#e7ac19d2a0385414fa8f847c4d01855f49383fdb"
|
||||
integrity "sha1-56wZ0qA4VBT6j4R8TQGFX0k4P9s= sha512-qJPyYskLyuOOON1rFjO5xHmeVduaNJGd6AgeWqq8F6rVE+n79Jr7wdML2qrODoAeb63zztd5JB9Cc8WSWV/rig=="
|
||||
dependencies:
|
||||
check-more-types "2.24.0"
|
||||
disparity "2.0.0"
|
||||
folktale "2.0.1"
|
||||
lazy-ass "1.6.0"
|
||||
strip-ansi "4.0.0"
|
||||
variable-diff "1.1.0"
|
||||
|
||||
snap-shot-core@6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.npmjs.org/snap-shot-core/-/snap-shot-core-6.0.1.tgz#b74dc57234848dd96eaa68e40d3bdb5a9c350e61"
|
||||
integrity "sha1-t03FcjSEjdluqmjkDTvbWpw1DmE= sha512-3jbkQIrpd5PQXOSRTsa7fAKw9vNI4uIdo7bnznOpIqKBLSzWTuakRC6b334c2rqPAI/QrXokcs1vEGJTeM1dsQ=="
|
||||
dependencies:
|
||||
check-more-types "2.24.0"
|
||||
common-tags "1.8.0"
|
||||
debug "3.1.0"
|
||||
escape-quotes "1.0.2"
|
||||
folktale "2.1.0"
|
||||
is-ci "1.1.0"
|
||||
jsesc "2.5.1"
|
||||
lazy-ass "1.6.0"
|
||||
mkdirp "0.5.1"
|
||||
ramda "0.25.0"
|
||||
|
||||
snap-shot-it@5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.npmjs.org/snap-shot-it/-/snap-shot-it-5.0.1.tgz#0755fc146c1264bfafe7b9e77e8524a2bdd56178"
|
||||
integrity "sha1-B1X8FGwSZL+v57nnfoUkor3VYXg= sha512-TSlYi4ceHhd/Fcy3EE6Db+kjPPI81eAXOhWm69BfPQ5MriPV083CDa3grFW/yJE/bXEVMZ7MB/v84tQkqWjBJQ=="
|
||||
dependencies:
|
||||
"@bahmutov/data-driven" "1.0.0"
|
||||
check-more-types "2.24.0"
|
||||
debug "3.1.0"
|
||||
has-only "1.1.1"
|
||||
ramda "0.25.0"
|
||||
snap-shot-compare "2.7.1"
|
||||
snap-shot-core "6.0.1"
|
||||
|
||||
string-width@^4.1.0, string-width@^4.2.0:
|
||||
version "4.2.3"
|
||||
resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||
integrity "sha1-JpxxF9J7Ba0uU2gwqOyJXvnG0BA= sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="
|
||||
dependencies:
|
||||
emoji-regex "^8.0.0"
|
||||
is-fullwidth-code-point "^3.0.0"
|
||||
strip-ansi "^6.0.1"
|
||||
|
||||
strip-ansi@4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
|
||||
integrity "sha1-qEeQIusaw2iocTibY1JixQXuNo8= sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow=="
|
||||
dependencies:
|
||||
ansi-regex "^3.0.0"
|
||||
|
||||
strip-ansi@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
|
||||
integrity "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg=="
|
||||
dependencies:
|
||||
ansi-regex "^2.0.0"
|
||||
|
||||
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||
integrity "sha1-nibGPTD1NEPpSJSVshBdN7Z6hdk= sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="
|
||||
dependencies:
|
||||
ansi-regex "^5.0.1"
|
||||
|
||||
strip-json-comments@3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
|
||||
integrity "sha1-MfEoGzgyYwQ0gxwxDAHMzajL4AY= sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="
|
||||
|
||||
supports-color@8.1.1:
|
||||
version "8.1.1"
|
||||
resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c"
|
||||
integrity "sha1-zW/BfihQDP9WwbhsCn/UpUpzAFw= sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="
|
||||
dependencies:
|
||||
has-flag "^4.0.0"
|
||||
|
||||
supports-color@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
|
||||
integrity "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g=="
|
||||
|
||||
supports-color@^7.1.0:
|
||||
version "7.2.0"
|
||||
resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
|
||||
integrity "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo= sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="
|
||||
dependencies:
|
||||
has-flag "^4.0.0"
|
||||
|
||||
terminal-banner@1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.npmjs.org/terminal-banner/-/terminal-banner-1.1.0.tgz#ef81ce7d9d7e541a81d09eb2c0257c3d5463c3ea"
|
||||
integrity "sha1-74HOfZ1+VBqB0J6ywCV8PVRjw+o= sha512-A70B8Io5gGOTKQuoqU6LUPLouNd9DvFLgw3cPh6bfrQjdy7HWW1t04VJfQwjTnygTVDX0xremaj1cg3SQaCGyg=="
|
||||
|
||||
to-regex-range@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
|
||||
integrity "sha1-FkjESq58jZiKMmAY7XL1tN0DkuQ= sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="
|
||||
dependencies:
|
||||
is-number "^7.0.0"
|
||||
|
||||
variable-diff@1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.npmjs.org/variable-diff/-/variable-diff-1.1.0.tgz#d2bd5c66db76c13879d96e6a306edc989df978da"
|
||||
integrity "sha1-0r1cZtt2wTh52W5qMG7cmJ35eNo= sha512-0Jk/MsCNtL/fCuVIbsLxwXpABGZCzN57btcPbSsjOOAwkdHJ3Y58fo8BoUfG7jghnvglbwo+5Hk1KOJ2W2Ormw=="
|
||||
dependencies:
|
||||
chalk "^1.1.1"
|
||||
object-assign "^4.0.1"
|
||||
|
||||
which@2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
|
||||
integrity "sha1-fGqN0KY2oDJ+ELWckobu6T8/UbE= sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="
|
||||
dependencies:
|
||||
isexe "^2.0.0"
|
||||
|
||||
workerpool@6.2.0:
|
||||
version "6.2.0"
|
||||
resolved "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz#827d93c9ba23ee2019c3ffaff5c27fccea289e8b"
|
||||
integrity "sha1-gn2Tyboj7iAZw/+v9cJ/zOoonos= sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A=="
|
||||
|
||||
wrap-ansi@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
||||
integrity "sha1-Z+FFz/UQpqaYS98RUpEdadLrnkM= sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="
|
||||
dependencies:
|
||||
ansi-styles "^4.0.0"
|
||||
string-width "^4.1.0"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
wrappy@1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||
integrity "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
||||
|
||||
y18n@^5.0.5:
|
||||
version "5.0.8"
|
||||
resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
|
||||
integrity "sha1-f0k00PfKjFb5UxSTndzS3ZHOHVU= sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="
|
||||
|
||||
yargs-parser@20.2.4:
|
||||
version "20.2.4"
|
||||
resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54"
|
||||
integrity "sha1-tCiQ8UVmeW+Fro46JSkNIF8VSlQ= sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA=="
|
||||
|
||||
yargs-parser@^20.2.2:
|
||||
version "20.2.9"
|
||||
resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee"
|
||||
integrity "sha1-LrfcOwKJcY/ClfNidThFxBoMlO4= sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w=="
|
||||
|
||||
yargs-unparser@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb"
|
||||
integrity "sha1-8TH5ImkRrl2a04xDL+gJNmwjJes= sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA=="
|
||||
dependencies:
|
||||
camelcase "^6.0.0"
|
||||
decamelize "^4.0.0"
|
||||
flat "^5.0.2"
|
||||
is-plain-obj "^2.1.0"
|
||||
|
||||
yargs@16.2.0:
|
||||
version "16.2.0"
|
||||
resolved "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66"
|
||||
integrity "sha1-HIK/D2tqZur85+8w43b0mhJHf2Y= sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw=="
|
||||
dependencies:
|
||||
cliui "^7.0.2"
|
||||
escalade "^3.1.1"
|
||||
get-caller-file "^2.0.5"
|
||||
require-directory "^2.1.1"
|
||||
string-width "^4.2.0"
|
||||
y18n "^5.0.5"
|
||||
yargs-parser "^20.2.2"
|
||||
|
||||
yocto-queue@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
|
||||
integrity "sha1-ApTrPe4FAo0x7hpfosVWpqrxChs= sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="
|
||||
@@ -33,8 +33,10 @@ cd $TEST_PROJECT_DIR
|
||||
|
||||
export CYPRESS_INSTALL_BINARY=$ZIP_PATH
|
||||
export CYPRESS_CACHE_FOLDER=/tmp/CYPRESS_CACHE_FOLDER/
|
||||
export npm_config_cache=/tmp/npm_config_cache/
|
||||
export npm_config_package_lock=false
|
||||
|
||||
npm install --save-dev --unsafe-perm --allow-root $CLI_PATH
|
||||
npx npm@latest install --unsafe-perm --allow-root --force file:$CLI_PATH
|
||||
|
||||
PATH=$PATH:./node_modules/.bin
|
||||
|
||||
|
||||
13
system-tests/test-binary/module_api_spec.ts
Normal file
13
system-tests/test-binary/module_api_spec.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import systemTests from '../lib/system-tests'
|
||||
|
||||
describe('module API', () => {
|
||||
systemTests.it('can run module API Mocha spec', {
|
||||
timeout: 240000,
|
||||
dockerImage: 'cypress/base:12',
|
||||
withBinary: true,
|
||||
project: 'module-api',
|
||||
browser: 'electron',
|
||||
command: 'yarn',
|
||||
args: ['test'],
|
||||
})
|
||||
})
|
||||
76
yarn.lock
76
yarn.lock
@@ -2504,21 +2504,6 @@
|
||||
through2 "^2.0.0"
|
||||
watchify "3.11.1"
|
||||
|
||||
"@cypress/bumpercar@2.0.12":
|
||||
version "2.0.12"
|
||||
resolved "https://registry.yarnpkg.com/@cypress/bumpercar/-/bumpercar-2.0.12.tgz#5e0231db1b4782fb92ce96c84ca0c2f1477c3201"
|
||||
integrity sha512-O+NvKPWbKvNzotX+Orb4+dI/0KTydco4EdNBilG+8muItTZ7bWjOs+iDZY48Bjkuh78+k42eBgAEgbJWYSqSbA==
|
||||
dependencies:
|
||||
"@cypress/coffee-script" "0.1.2"
|
||||
axios "0.19.0"
|
||||
bluebird "3.7.1"
|
||||
check-more-types "^2.24.0"
|
||||
debug "^3.1.0"
|
||||
lazy-ass "^1.6.0"
|
||||
lodash "^4.17.4"
|
||||
parse-github-repo-url "^1.4.1"
|
||||
ramda "^0.26.0"
|
||||
|
||||
"@cypress/code-coverage@3.8.1":
|
||||
version "3.8.1"
|
||||
resolved "https://registry.yarnpkg.com/@cypress/code-coverage/-/code-coverage-3.8.1.tgz#913f34b1063423cc881988fa3b452da170aea5b6"
|
||||
@@ -2561,13 +2546,6 @@
|
||||
js-yaml "3.14.1"
|
||||
nyc "15.1.0"
|
||||
|
||||
"@cypress/coffee-script@0.1.2":
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@cypress/coffee-script/-/coffee-script-0.1.2.tgz#2721cf60ef65ce47b3895aa0b8e84771868bc011"
|
||||
integrity sha1-JyHPYO9lzkeziVqguOhHcYaLwBE=
|
||||
dependencies:
|
||||
coffee-script "1.12.5"
|
||||
|
||||
"@cypress/commit-info@2.2.0":
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@cypress/commit-info/-/commit-info-2.2.0.tgz#6086d478975edb7ac7c9ffdd5cfd5be2b9fe44f2"
|
||||
@@ -6283,16 +6261,6 @@
|
||||
universal-user-agent "^2.0.0"
|
||||
url-template "^2.0.8"
|
||||
|
||||
"@octokit/rest@18.10.0", "@octokit/rest@^18.0.0":
|
||||
version "18.10.0"
|
||||
resolved "https://registry.npmjs.org/@octokit/rest/-/rest-18.10.0.tgz#8a0add9611253e0e31d3ed5b4bc941a3795a7648"
|
||||
integrity sha512-esHR5OKy38bccL/sajHqZudZCvmv4yjovMJzyXlphaUo7xykmtOdILGJ3aAm0mFHmMLmPFmDMJXf39cAjNJsrw==
|
||||
dependencies:
|
||||
"@octokit/core" "^3.5.1"
|
||||
"@octokit/plugin-paginate-rest" "^2.16.0"
|
||||
"@octokit/plugin-request-log" "^1.0.4"
|
||||
"@octokit/plugin-rest-endpoint-methods" "^5.9.0"
|
||||
|
||||
"@octokit/rest@^16.28.4":
|
||||
version "16.43.2"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-16.43.2.tgz#c53426f1e1d1044dee967023e3279c50993dd91b"
|
||||
@@ -6315,6 +6283,16 @@
|
||||
once "^1.4.0"
|
||||
universal-user-agent "^4.0.0"
|
||||
|
||||
"@octokit/rest@^18.0.0":
|
||||
version "18.10.0"
|
||||
resolved "https://registry.npmjs.org/@octokit/rest/-/rest-18.10.0.tgz#8a0add9611253e0e31d3ed5b4bc941a3795a7648"
|
||||
integrity sha512-esHR5OKy38bccL/sajHqZudZCvmv4yjovMJzyXlphaUo7xykmtOdILGJ3aAm0mFHmMLmPFmDMJXf39cAjNJsrw==
|
||||
dependencies:
|
||||
"@octokit/core" "^3.5.1"
|
||||
"@octokit/plugin-paginate-rest" "^2.16.0"
|
||||
"@octokit/plugin-request-log" "^1.0.4"
|
||||
"@octokit/plugin-rest-endpoint-methods" "^5.9.0"
|
||||
|
||||
"@octokit/types@^2.0.0", "@octokit/types@^2.0.1":
|
||||
version "2.16.2"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/types/-/types-2.16.2.tgz#4c5f8da3c6fecf3da1811aef678fda03edac35d2"
|
||||
@@ -12485,14 +12463,6 @@ aws4@^1.8.0:
|
||||
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59"
|
||||
integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==
|
||||
|
||||
axios@0.19.0:
|
||||
version "0.19.0"
|
||||
resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.0.tgz#8e09bff3d9122e133f7b8101c8fbdd00ed3d2ab8"
|
||||
integrity sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==
|
||||
dependencies:
|
||||
follow-redirects "1.5.10"
|
||||
is-buffer "^2.0.2"
|
||||
|
||||
axios@0.21.2, axios@^0.21.1:
|
||||
version "0.21.2"
|
||||
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.2.tgz#21297d5084b2aeeb422f5d38e7be4fbb82239017"
|
||||
@@ -15871,7 +15841,7 @@ coffee-loader@^0.9.0:
|
||||
dependencies:
|
||||
loader-utils "^1.0.2"
|
||||
|
||||
coffee-script@1.12.5, coffee-script@^1.10.0:
|
||||
coffee-script@^1.10.0:
|
||||
version "1.12.5"
|
||||
resolved "https://registry.yarnpkg.com/coffee-script/-/coffee-script-1.12.5.tgz#809f4585419112bbfe46a073ad7543af18c27346"
|
||||
integrity sha1-gJ9FhUGRErv+RqBzrXVDrxjCc0Y=
|
||||
@@ -17896,7 +17866,7 @@ debug@2.6.8:
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
debug@3.1.0, debug@=3.1.0, debug@~3.1.0:
|
||||
debug@3.1.0, debug@~3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
|
||||
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
|
||||
@@ -21595,13 +21565,6 @@ folktale@2.3.2:
|
||||
resolved "https://registry.yarnpkg.com/folktale/-/folktale-2.3.2.tgz#38231b039e5ef36989920cbf805bf6b227bf4fd4"
|
||||
integrity sha512-+8GbtQBwEqutP0v3uajDDoN64K2ehmHd0cjlghhxh0WpcfPzAIjPA03e1VvHlxL02FVGR0A6lwXsNQKn3H1RNQ==
|
||||
|
||||
follow-redirects@1.5.10:
|
||||
version "1.5.10"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a"
|
||||
integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==
|
||||
dependencies:
|
||||
debug "=3.1.0"
|
||||
|
||||
follow-redirects@^1.0.0, follow-redirects@^1.14.0:
|
||||
version "1.14.7"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.7.tgz#2004c02eb9436eee9a21446a6477debf17e81685"
|
||||
@@ -24800,7 +24763,7 @@ is-buffer@^1.0.2, is-buffer@^1.1.0, is-buffer@^1.1.3, is-buffer@^1.1.5, is-buffe
|
||||
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
|
||||
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
|
||||
|
||||
is-buffer@^2.0.0, is-buffer@^2.0.2, is-buffer@~2.0.3:
|
||||
is-buffer@^2.0.0, is-buffer@~2.0.3:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191"
|
||||
integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==
|
||||
@@ -28640,15 +28603,6 @@ make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0:
|
||||
dependencies:
|
||||
semver "^6.0.0"
|
||||
|
||||
"make-empty-github-commit@https://github.com/cypress-io/make-empty-github-commit.git#4a592aedb776ba2f4cc88979055315a53eec42ee":
|
||||
version "0.0.0-development"
|
||||
resolved "https://github.com/cypress-io/make-empty-github-commit.git#4a592aedb776ba2f4cc88979055315a53eec42ee"
|
||||
dependencies:
|
||||
"@octokit/rest" "18.10.0"
|
||||
debug "3.1.0"
|
||||
minimist "1.2.5"
|
||||
parse-github-repo-url "1.4.1"
|
||||
|
||||
make-error@^1, make-error@^1.1.1:
|
||||
version "1.3.6"
|
||||
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
|
||||
@@ -32289,7 +32243,7 @@ parse-filepath@^1.0.1, parse-filepath@^1.0.2:
|
||||
map-cache "^0.2.0"
|
||||
path-root "^0.1.1"
|
||||
|
||||
parse-github-repo-url@1.4.1, parse-github-repo-url@^1.3.0, parse-github-repo-url@^1.4.1:
|
||||
parse-github-repo-url@^1.3.0:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/parse-github-repo-url/-/parse-github-repo-url-1.4.1.tgz#9e7d8bb252a6cb6ba42595060b7bf6df3dbc1f50"
|
||||
integrity sha1-nn2LslKmy2ukJZUGC3v23z28H1A=
|
||||
@@ -34766,7 +34720,7 @@ ramda@0.25.0, ramda@^0.25.0:
|
||||
resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.25.0.tgz#8fdf68231cffa90bc2f9460390a0cb74a29b29a9"
|
||||
integrity sha512-GXpfrYVPwx3K7RQ6aYT8KPS8XViSXUVJT1ONhoKPE9VAleW42YE+U+8VEyGWt41EnEQW7gwecYJriTI0pKoecQ==
|
||||
|
||||
ramda@0.26.1, ramda@^0.26.0:
|
||||
ramda@0.26.1:
|
||||
version "0.26.1"
|
||||
resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.26.1.tgz#8d41351eb8111c55353617fc3bbffad8e4d35d06"
|
||||
integrity sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ==
|
||||
|
||||
Reference in New Issue
Block a user