diff --git a/cli/package.json b/cli/package.json index 7de3045a15..0e94a58600 100644 --- a/cli/package.json +++ b/cli/package.json @@ -49,7 +49,6 @@ "lodash": "^4.17.19", "log-symbols": "^4.0.0", "minimist": "^1.2.5", - "moment": "^2.29.1", "ospath": "^1.2.2", "pretty-bytes": "^5.4.1", "ramda": "~0.26.1", diff --git a/cli/types/cy-moment.d.ts b/cli/types/cy-moment.d.ts deleted file mode 100644 index d68f10b9b5..0000000000 --- a/cli/types/cy-moment.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import moment = require('moment') -export = Moment -export as namespace Moment - -declare namespace Moment { - type MomentStatic = typeof moment -} diff --git a/cli/types/cypress.d.ts b/cli/types/cypress.d.ts index c0aee1ac19..88ec37cc32 100644 --- a/cli/types/cypress.d.ts +++ b/cli/types/cypress.d.ts @@ -176,18 +176,6 @@ declare namespace Cypress { * @see https://on.cypress.io/minimatch */ minimatch: typeof Minimatch.minimatch - /** - * @deprecated Will be removed in a future version. - * Consider including your own datetime formatter in your tests. - * - * Cypress automatically includes moment.js and exposes it as Cypress.moment. - * - * @see https://on.cypress.io/moment - * @see http://momentjs.com/ - * @example - * const todaysDate = Cypress.moment().format("MMM DD, YYYY") - */ - moment: Moment.MomentStatic /** * Cypress automatically includes Bluebird and exposes it as Cypress.Promise. * diff --git a/cli/types/index.d.ts b/cli/types/index.d.ts index c66f78aa11..607d5df14a 100644 --- a/cli/types/index.d.ts +++ b/cli/types/index.d.ts @@ -9,7 +9,6 @@ /// /// -/// /// /// /// diff --git a/cli/types/tests/cypress-tests.ts b/cli/types/tests/cypress-tests.ts index 000cf8fb83..c2ce047ec1 100644 --- a/cli/types/tests/cypress-tests.ts +++ b/cli/types/tests/cypress-tests.ts @@ -5,14 +5,6 @@ namespace CypressLodashTests { }) } -namespace CypressMomentTests { - Cypress.moment() // $ExpectType Moment - Cypress.moment('1982-08-23') // $ExpectType Moment - Cypress.moment(Date()) // $ExpectType Moment - Cypress.moment(Date()).format() // $ExpectType string - Cypress.moment().startOf('week') // $ExpectType Moment -} - namespace CypressSinonTests { Cypress.sinon // $ExpectType SinonStatic diff --git a/packages/desktop-gui/index.d.ts b/packages/desktop-gui/index.d.ts index 821afbbe33..f310b6a354 100644 --- a/packages/desktop-gui/index.d.ts +++ b/packages/desktop-gui/index.d.ts @@ -1,6 +1,5 @@ /// /// -/// /// /// diff --git a/packages/driver/cypress/integration/commands/actions/type_errors_spec.js b/packages/driver/cypress/integration/commands/actions/type_errors_spec.js index eb0f69d4c5..9422d35b3c 100644 --- a/packages/driver/cypress/integration/commands/actions/type_errors_spec.js +++ b/packages/driver/cypress/integration/commands/actions/type_errors_spec.js @@ -324,7 +324,7 @@ If you want to skip parsing special character sequences and type the text exactl it('throws when chars is not a string', function (done) { cy.on('fail', (err) => { expect(this.logs.length).to.eq(2) - expect(err.message).to.eq('Typing into a `date` input with `cy.type()` requires a valid date with the format `yyyy-MM-dd`. You passed: `1989`') + expect(err.message).to.eq('Typing into a `date` input with `cy.type()` requires a valid date with the format `YYYY-MM-DD`. You passed: `1989`') expect(err.docsUrl).to.eq('https://on.cypress.io/type') done() }) @@ -335,7 +335,7 @@ If you want to skip parsing special character sequences and type the text exactl it('throws when chars is invalid format', function (done) { cy.on('fail', (err) => { expect(this.logs.length).to.eq(2) - expect(err.message).to.eq('Typing into a `date` input with `cy.type()` requires a valid date with the format `yyyy-MM-dd`. You passed: `01-01-1989`') + expect(err.message).to.eq('Typing into a `date` input with `cy.type()` requires a valid date with the format `YYYY-MM-DD`. You passed: `01-01-1989`') expect(err.docsUrl).to.eq('https://on.cypress.io/type') done() }) @@ -343,14 +343,15 @@ If you want to skip parsing special character sequences and type the text exactl cy.get('#date-without-value').type('01-01-1989') }) - it('throws when chars is invalid date', function (done) { + it('throws when chars is non-existent date', function (done) { cy.on('fail', (err) => { expect(this.logs.length).to.eq(2) - expect(err.message).to.eq('Typing into a `date` input with `cy.type()` requires a valid date with the format `yyyy-MM-dd`. You passed: `1989-04-31`') + expect(err.message).to.eq('Typing into a `date` input with `cy.type()` requires a valid date with the format `YYYY-MM-DD`. You passed: `1989-04-31`') expect(err.docsUrl).to.eq('https://on.cypress.io/type') done() }) + // there are not 31 days in April cy.get('#date-without-value').type('1989-04-31') }) }) @@ -359,7 +360,7 @@ If you want to skip parsing special character sequences and type the text exactl it('throws when chars is not a string', function (done) { cy.on('fail', (err) => { expect(this.logs.length).to.eq(2) - expect(err.message).to.eq('Typing into a `month` input with `cy.type()` requires a valid month with the format `yyyy-MM`. You passed: `6`') + expect(err.message).to.eq('Typing into a `month` input with `cy.type()` requires a valid month with the format `YYYY-MM`. You passed: `6`') expect(err.docsUrl).to.eq('https://on.cypress.io/type') done() }) @@ -370,7 +371,7 @@ If you want to skip parsing special character sequences and type the text exactl it('throws when chars is invalid format', function (done) { cy.on('fail', (err) => { expect(this.logs.length).to.eq(2) - expect(err.message).to.eq('Typing into a `month` input with `cy.type()` requires a valid month with the format `yyyy-MM`. You passed: `01/2000`') + expect(err.message).to.eq('Typing into a `month` input with `cy.type()` requires a valid month with the format `YYYY-MM`. You passed: `01/2000`') expect(err.docsUrl).to.eq('https://on.cypress.io/type') done() }) @@ -381,7 +382,7 @@ If you want to skip parsing special character sequences and type the text exactl it('throws when chars is invalid month', function (done) { cy.on('fail', (err) => { expect(this.logs.length).to.eq(2) - expect(err.message).to.eq('Typing into a `month` input with `cy.type()` requires a valid month with the format `yyyy-MM`. You passed: `1989-13`') + expect(err.message).to.eq('Typing into a `month` input with `cy.type()` requires a valid month with the format `YYYY-MM`. You passed: `1989-13`') expect(err.docsUrl).to.eq('https://on.cypress.io/type') done() }) @@ -401,14 +402,14 @@ If you want to skip parsing special character sequences and type the text exactl // it "throws when chars is invalid format", (done) -> // cy.on "fail", (err) => // expect(@logs.length).to.eq(2) - // expect(err.message).to.eq("Typing into a week input with cy.type() requires a valid week with the format 'yyyy-Www', where W is the literal character 'W' and ww is the week number (00-53). You passed: 2005/W18") + // expect(err.message).to.eq("Typing into a week input with cy.type() requires a valid week with the format 'YYYY-Www', where W is the literal character 'W' and ww is the week number (00-53). You passed: 2005/W18") // done() context('[type=week]', () => { it('throws when chars is not a string', function (done) { cy.on('fail', (err) => { expect(this.logs.length).to.eq(2) - expect(err.message).to.eq('Typing into a `week` input with `cy.type()` requires a valid week with the format `yyyy-Www`, where `W` is the literal character `W` and `ww` is the week number (00-53). You passed: `23`') + expect(err.message).to.eq('Typing into a `week` input with `cy.type()` requires a valid week with the format `YYYY-Www`, where `W` is the literal character `W` and `ww` is the week number (00-53). You passed: `23`') expect(err.docsUrl).to.eq('https://on.cypress.io/type') done() }) @@ -419,7 +420,7 @@ If you want to skip parsing special character sequences and type the text exactl it('throws when chars is invalid format', function (done) { cy.on('fail', (err) => { expect(this.logs.length).to.eq(2) - expect(err.message).to.eq('Typing into a `week` input with `cy.type()` requires a valid week with the format `yyyy-Www`, where `W` is the literal character `W` and `ww` is the week number (00-53). You passed: `2005/W18`') + expect(err.message).to.eq('Typing into a `week` input with `cy.type()` requires a valid week with the format `YYYY-Www`, where `W` is the literal character `W` and `ww` is the week number (00-53). You passed: `2005/W18`') expect(err.docsUrl).to.eq('https://on.cypress.io/type') done() }) @@ -430,7 +431,7 @@ If you want to skip parsing special character sequences and type the text exactl it('throws when chars is invalid week', function (done) { cy.on('fail', (err) => { expect(this.logs.length).to.eq(2) - expect(err.message).to.eq('Typing into a `week` input with `cy.type()` requires a valid week with the format `yyyy-Www`, where `W` is the literal character `W` and `ww` is the week number (00-53). You passed: `1995-W60`') + expect(err.message).to.eq('Typing into a `week` input with `cy.type()` requires a valid week with the format `YYYY-Www`, where `W` is the literal character `W` and `ww` is the week number (00-53). You passed: `1995-W60`') expect(err.docsUrl).to.eq('https://on.cypress.io/type') done() }) diff --git a/packages/driver/cypress/integration/commands/actions/type_spec.js b/packages/driver/cypress/integration/commands/actions/type_spec.js index 19d299db82..cb7a48b902 100644 --- a/packages/driver/cypress/integration/commands/actions/type_spec.js +++ b/packages/driver/cypress/integration/commands/actions/type_spec.js @@ -1608,7 +1608,7 @@ describe('src/cy/commands/actions/type - #type', () => { it('errors when invalid datetime', (done) => { cy.on('fail', (err) => { expect(err.message).contain('datetime') - expect(err.message).contain('yyyy-MM-ddThh:mm') + expect(err.message).contain('YYYY-MM-DDThh:mm') done() }) diff --git a/packages/driver/cypress/integration/util/moment_spec.js b/packages/driver/cypress/integration/util/moment_spec.js deleted file mode 100644 index fb8827ad81..0000000000 --- a/packages/driver/cypress/integration/util/moment_spec.js +++ /dev/null @@ -1,28 +0,0 @@ -context('#moment', () => { - it('logs deprecation warning', () => { - cy.stub(Cypress.utils, 'warning') - - Cypress.moment() - expect(Cypress.utils.warning).to.be.calledWith('`Cypress.moment` has been deprecated and will be removed in a future release. Consider migrating to a different datetime formatter.') - }) - - it('still has other moment properties', () => { - expect(Cypress.moment.duration).to.be.a('function') - expect(Cypress.moment.isDate()).to.be.false - expect(Cypress.moment.isDate(new Date())).to.be.true - }) - - it('logs deprecation warning when using duration', () => { - cy.stub(Cypress.utils, 'warning') - - Cypress.moment.duration() - expect(Cypress.utils.warning).to.be.calledWith('`Cypress.moment` has been deprecated and will be removed in a future release. Consider migrating to a different datetime formatter.') - }) - - it('logs deprecation warning when using isDate', () => { - cy.stub(Cypress.utils, 'warning') - - Cypress.moment.isDate() - expect(Cypress.utils.warning).to.be.calledWith('`Cypress.moment` has been deprecated and will be removed in a future release. Consider migrating to a different datetime formatter.') - }) -}) diff --git a/packages/driver/package.json b/packages/driver/package.json index d13fb31e10..1085569f4a 100644 --- a/packages/driver/package.json +++ b/packages/driver/package.json @@ -41,6 +41,7 @@ "compression": "1.7.4", "cors": "2.8.5", "cypress-multi-reporters": "1.4.0", + "dayjs": "^1.10.3", "debug": "4.3.1", "error-stack-parser": "2.0.6", "errorhandler": "1.5.1", @@ -58,7 +59,6 @@ "minimatch": "3.0.4", "minimist": "1.2.5", "mocha": "7.0.1", - "moment": "2.29.1", "morgan": "1.9.1", "ordinal": "1.0.3", "react-15.6.1": "npm:react@15.6.1", diff --git a/packages/driver/src/config/moment.js b/packages/driver/src/config/moment.js deleted file mode 100644 index 6abbae37af..0000000000 --- a/packages/driver/src/config/moment.js +++ /dev/null @@ -1,19 +0,0 @@ -const moment = require('moment') - -moment.updateLocale('en', { - relativeTime: { - future: 'in %s', - past: '%s ago', - s: 's', - m: '1m', - mm: '%dm', - h: '1h', - hh: '%dh', - d: '1d', - dd: '%dd', - M: '1mo', - MM: '%dmo', - y: '1y', - yy: '%dy', - }, -}) diff --git a/packages/driver/src/cy/keyboard.ts b/packages/driver/src/cy/keyboard.ts index 1dcdb03c2e..0ea6c34a06 100644 --- a/packages/driver/src/cy/keyboard.ts +++ b/packages/driver/src/cy/keyboard.ts @@ -1,7 +1,7 @@ import Promise from 'bluebird' import Debug from 'debug' import _ from 'lodash' -import moment from 'moment' +import dayjs from 'dayjs' import $errUtils from '../cypress/error_utils' import { USKeyboard } from '../cypress/UsKeyboardLayout' import * as $dom from '../dom' @@ -473,10 +473,15 @@ const validateTyping = ( if (isDate) { dateChars = dateRe.exec(chars) + const dateExists = (date) => { + // dayjs rounds up dates that don't exist to valid dates + return dayjs(date, 'YYYY-MM-DD').format('YYYY-MM-DD') === date + } + if ( _.isString(chars) && dateChars && - moment(dateChars[0]).isValid() + dateExists(dateChars[0]) ) { skipCheckUntilIndex = _getEndIndex(chars, dateChars[0]) diff --git a/packages/driver/src/cypress.js b/packages/driver/src/cypress.js index db85922a1f..d25f66343c 100644 --- a/packages/driver/src/cypress.js +++ b/packages/driver/src/cypress.js @@ -2,7 +2,6 @@ const _ = require('lodash') const $ = require('jquery') const blobUtil = require('blob-util') const minimatch = require('minimatch') -const moment = require('moment') const Promise = require('bluebird') const sinon = require('sinon') const lolex = require('lolex') @@ -566,28 +565,6 @@ class $Cypress { } } -function wrapMoment (moment) { - function deprecatedFunction (...args) { - $errUtils.warnByPath('moment.deprecated') - - return moment.apply(moment, args) - } - // copy all existing properties from "moment" like "moment.duration" - _.keys(moment).forEach((key) => { - const value = moment[key] - - if (_.isFunction(value)) { - // recursively wrap any property that can be called by the user - // so that Cypress.moment.duration() shows deprecated message - deprecatedFunction[key] = wrapMoment(value) - } else { - deprecatedFunction[key] = value - } - }) - - return deprecatedFunction -} - // attach to $Cypress to access // all of the constructors // to enable users to monkeypatch @@ -613,7 +590,6 @@ $Cypress.prototype.Screenshot = $Screenshot $Cypress.prototype.SelectorPlayground = $SelectorPlayground $Cypress.prototype.utils = $utils $Cypress.prototype._ = _ -$Cypress.prototype.moment = wrapMoment(moment) $Cypress.prototype.Blob = blobUtil $Cypress.prototype.Promise = Promise $Cypress.prototype.minimatch = minimatch diff --git a/packages/driver/src/cypress/error_messages.js b/packages/driver/src/cypress/error_messages.js index 175bc35485..4f43b109c0 100644 --- a/packages/driver/src/cypress/error_messages.js +++ b/packages/driver/src/cypress/error_messages.js @@ -872,10 +872,6 @@ module.exports = { }, - moment: { - deprecated: `\`Cypress.moment\` has been deprecated and will be removed in a future release. Consider migrating to a different datetime formatter.`, - }, - navigation: { cross_origin ({ message, originPolicy, configFile }) { return { @@ -1620,15 +1616,15 @@ module.exports = { docsUrl: 'https://on.cypress.io/type', }, invalid_date: { - message: `Typing into a \`date\` input with ${cmd('type')} requires a valid date with the format \`yyyy-MM-dd\`. You passed: \`{{chars}}\``, + message: `Typing into a \`date\` input with ${cmd('type')} requires a valid date with the format \`YYYY-MM-DD\`. You passed: \`{{chars}}\``, docsUrl: 'https://on.cypress.io/type', }, invalid_datetime: { - message: `Typing into a datetime input with ${cmd('type')} requires a valid datetime with the format \`yyyy-MM-ddThh:mm\`, for example \`2017-06-01T08:30\`. You passed: \`{{chars}}\``, + message: `Typing into a datetime input with ${cmd('type')} requires a valid datetime with the format \`YYYY-MM-DDThh:mm\`, for example \`2017-06-01T08:30\`. You passed: \`{{chars}}\``, docsUrl: 'https://on.cypress.io/type', }, invalid_month: { - message: `Typing into a \`month\` input with ${cmd('type')} requires a valid month with the format \`yyyy-MM\`. You passed: \`{{chars}}\``, + message: `Typing into a \`month\` input with ${cmd('type')} requires a valid month with the format \`YYYY-MM\`. You passed: \`{{chars}}\``, docsUrl: 'https://on.cypress.io/type', }, invalid_time: { @@ -1636,7 +1632,7 @@ module.exports = { docsUrl: 'https://on.cypress.io/type', }, invalid_week: { - message: `Typing into a \`week\` input with ${cmd('type')} requires a valid week with the format \`yyyy-Www\`, where \`W\` is the literal character \`W\` and \`ww\` is the week number (00-53). You passed: \`{{chars}}\``, + message: `Typing into a \`week\` input with ${cmd('type')} requires a valid week with the format \`YYYY-Www\`, where \`W\` is the literal character \`W\` and \`ww\` is the week number (00-53). You passed: \`{{chars}}\``, docsUrl: 'https://on.cypress.io/type', }, multiple_elements: { diff --git a/packages/driver/src/cypress/runner.js b/packages/driver/src/cypress/runner.js index 0d638615ad..49115efe1c 100644 --- a/packages/driver/src/cypress/runner.js +++ b/packages/driver/src/cypress/runner.js @@ -1,7 +1,7 @@ /* eslint-disable prefer-rest-params */ /* globals Cypress */ const _ = require('lodash') -const moment = require('moment') +const dayjs = require('dayjs') const Promise = require('bluebird') const Pending = require('mocha/lib/pending') @@ -1274,7 +1274,7 @@ const create = (specWindow, mocha, Cypress, cy) => { run (fn) { if (_startTime == null) { - _startTime = moment().toJSON() + _startTime = dayjs().toJSON() } _runnerListeners(_runner, Cypress, _emissions, getTestById, getTest, setTest, getTestFromHookOrFindTest) diff --git a/packages/driver/src/cypress/utils.js b/packages/driver/src/cypress/utils.js index 2b77cb8c0c..efb16e3b58 100644 --- a/packages/driver/src/cypress/utils.js +++ b/packages/driver/src/cypress/utils.js @@ -1,7 +1,7 @@ const _ = require('lodash') const capitalize = require('underscore.string/capitalize') const methods = require('methods') -const moment = require('moment') +const dayjs = require('dayjs') const $jquery = require('../dom/jquery') const $Location = require('./location') @@ -280,7 +280,7 @@ module.exports = { }, addTwentyYears () { - return moment().add(20, 'years').unix() + return dayjs().add(20, 'year').unix() }, locReload (forceReload, win) { diff --git a/packages/driver/src/main.js b/packages/driver/src/main.js index 7043fcd6f8..6c01e575e8 100644 --- a/packages/driver/src/main.js +++ b/packages/driver/src/main.js @@ -3,6 +3,5 @@ require('setimmediate') require('./config/bluebird') require('./config/jquery') require('./config/lodash') -require('./config/moment') module.exports = require('./cypress') diff --git a/packages/reporter/index.d.ts b/packages/reporter/index.d.ts index 1c75cc27df..3c6f8f3f73 100644 --- a/packages/reporter/index.d.ts +++ b/packages/reporter/index.d.ts @@ -1,6 +1,5 @@ /// /// -/// /// /// diff --git a/packages/runner/index.d.ts b/packages/runner/index.d.ts index 821afbbe33..f310b6a354 100644 --- a/packages/runner/index.d.ts +++ b/packages/runner/index.d.ts @@ -1,6 +1,5 @@ /// /// -/// /// /// diff --git a/packages/server/test/support/fixtures/projects/e2e/cypress/integration/request_spec.js b/packages/server/test/support/fixtures/projects/e2e/cypress/integration/request_spec.js index c1577c5de4..f6f8229555 100644 --- a/packages/server/test/support/fixtures/projects/e2e/cypress/integration/request_spec.js +++ b/packages/server/test/support/fixtures/projects/e2e/cypress/integration/request_spec.js @@ -1,6 +1,8 @@ +const dayjs = require('dayjs') + describe('redirects + requests', () => { it('gets and sets cookies from cy.request', () => { - const oneMinuteFromNow = Cypress.moment().add(1, 'minute').unix() + const oneMinuteFromNow = dayjs().add(1, 'minute').unix() cy .request('http://localhost:2293/') diff --git a/packages/ui-components/index.d.ts b/packages/ui-components/index.d.ts index 821afbbe33..f310b6a354 100644 --- a/packages/ui-components/index.d.ts +++ b/packages/ui-components/index.d.ts @@ -1,6 +1,5 @@ /// /// -/// /// /// diff --git a/yarn.lock b/yarn.lock index df920f173e..802a9e5461 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12379,6 +12379,11 @@ dateformat@^3.0.0, dateformat@^3.0.2: resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== +dayjs@^1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.3.tgz#cf3357c8e7f508432826371672ebf376cb7d619b" + integrity sha512-/2fdLN987N8Ki7Id8BUN2nhuiRyxTLumQnSQf9CNncFCyqFsSKb9TNhzRYcC8K8eJSJOKvbvkImo/MKKhNi4iw== + dayjs@^1.9.3: version "1.9.3" resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.9.3.tgz#b7f94b22ad2a136a4ca02a01ab68ae893fe1a268" @@ -22960,11 +22965,6 @@ moment@2.17.0: resolved "https://registry.yarnpkg.com/moment/-/moment-2.17.0.tgz#a4c292e02aac5ddefb29a6eed24f51938dd3b74f" integrity sha1-pMKS4CqsXd77Kabu0k9Rk43Tt08= -moment@2.29.1, moment@^2.29.1: - version "2.29.1" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" - integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ== - moment@^2.27.0, moment@^2.9.0: version "2.29.0" resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.0.tgz#fcbef955844d91deb55438613ddcec56e86a3425"