diff --git a/packages/server/__snapshots__/cypress_spec.js b/packages/server/__snapshots__/cypress_spec.js index 1fb15ac8d9f..4de7d12abe7 100644 --- a/packages/server/__snapshots__/cypress_spec.js +++ b/packages/server/__snapshots__/cypress_spec.js @@ -310,3 +310,44 @@ The following configuration options are invalid: https://on.cypress.io/configuration ` + +exports['Long Dashboard URL'] = ` + +==================================================================================================== + + (Run Starting) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Cypress: 10.3.0 │ + │ Browser: Electron 99 (headless) │ + │ Specs: 1 found (app.cy.js) │ + │ Searched: cypress/e2e/**/*.cy.{js,jsx,ts,tsx} │ + │ Params: Tag: false, Group: electron-smoke-tests, Parallel: false │ + │ Run URL: http://dashboard.cypress.io/this-is-a-long-long-long-long-long-long-long-long-long │ + │ -long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-l │ + │ ong-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-lon │ + │ g-long-long-long-long-long-long-long-long-url │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + +──────────────────────────────────────────────────────────────────────────────────────────────────── + + Running: app.cy.js (1 of 1) + +==================================================================================================== + + (Run Finished) + + + Spec Tests Passing Failing Pending Skipped + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ ✖ 6ms 1 2 3 4 5 │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + ✖ 1 of 1 failed (100%) 6ms 1 2 3 4 5 + + +─────────────────────────────────────────────────────────────────────────────────────────────────────── + + Recorded Run: http://dashboard.cypress.io/this-is-a-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-long-url + +` diff --git a/packages/server/lib/modes/run.js b/packages/server/lib/modes/run.js index c27b8f251c0..eae73438a71 100644 --- a/packages/server/lib/modes/run.js +++ b/packages/server/lib/modes/run.js @@ -409,10 +409,9 @@ const renderSummaryTable = (runUrl) => { }) table4.push(['', '']) - table4.push([`Recorded Run: ${formatPath(runUrl, getWidth(table4, 0), 'gray')}`]) - console.log(terminal.renderTables(table4)) + console.log(` Recorded Run: ${formatPath(runUrl, undefined, 'gray')}`) console.log('') } } diff --git a/packages/server/test/integration/cypress_spec.js b/packages/server/test/integration/cypress_spec.js index c879bcaddc0..7bdfd1fa4ed 100644 --- a/packages/server/test/integration/cypress_spec.js +++ b/packages/server/test/integration/cypress_spec.js @@ -99,6 +99,53 @@ const snapshotConsoleLogs = function (name) { return snapshot(name, stripAnsi(args)) } +function mockEE () { + const ee = new EE() + + ee.kill = () => { + // ughh, would be nice to test logic inside the launcher + // that cleans up after the browser exit + // like calling client.close() if available to let the + // browser free any resources + return ee.emit('exit') + } + + ee.destroy = () => { + return ee.emit('closed') + } + + ee.isDestroyed = () => { + return false + } + + ee.loadURL = () => {} + ee.focusOnWebView = () => {} + ee.webContents = { + debugger: { + on: sinon.stub(), + attach: sinon.stub(), + sendCommand: sinon.stub().resolves(), + }, + getOSProcessId: sinon.stub(), + setUserAgent: sinon.stub(), + session: { + clearCache: sinon.stub().resolves(), + setProxy: sinon.stub().resolves(), + setUserAgent: sinon.stub(), + on: sinon.stub(), + removeListener: sinon.stub(), + webRequest: { + onBeforeSendHeaders () {}, + }, + }, + } + + ee.maximize = sinon.stub + ee.setSize = sinon.stub + + return ee +} + let ctx describe('lib/cypress', () => { @@ -909,48 +956,7 @@ describe('lib/cypress', () => { beforeEach(() => { browsers.open.restore() - const ee = new EE() - - ee.kill = () => { - // ughh, would be nice to test logic inside the launcher - // that cleans up after the browser exit - // like calling client.close() if available to let the - // browser free any resources - return ee.emit('exit') - } - - ee.destroy = () => { - return ee.emit('closed') - } - - ee.isDestroyed = () => { - return false - } - - ee.loadURL = () => {} - ee.focusOnWebView = () => {} - ee.webContents = { - debugger: { - on: sinon.stub(), - attach: sinon.stub(), - sendCommand: sinon.stub().resolves(), - }, - getOSProcessId: sinon.stub(), - setUserAgent: sinon.stub(), - session: { - clearCache: sinon.stub().resolves(), - setProxy: sinon.stub().resolves(), - setUserAgent: sinon.stub(), - on: sinon.stub(), - removeListener: sinon.stub(), - webRequest: { - onBeforeSendHeaders () {}, - }, - }, - } - - ee.maximize = sinon.stub - ee.setSize = sinon.stub + const ee = mockEE() sinon.stub(launch, 'launch').returns(ee) sinon.stub(Windows, 'create').returns(ee) @@ -1140,9 +1146,52 @@ describe('lib/cypress', () => { context('--record', () => { beforeEach(function () { sinon.stub(api, 'createRun').resolves() + const createInstanceStub = sinon.stub(api, 'createInstance') + + createInstanceStub.onFirstCall().resolves({ + spec: 'cypress/e2e/app.cy.js', + runs: [{}], + runId: '1', + claimedInstances: 1, + totalInstances: 1, + groupId: 1, + platform: 'linux', + machineId: 1, + }) + + createInstanceStub.onSecondCall().resolves({ + spec: null, + runs: [{}], + runId: '1', + claimedInstances: 1, + totalInstances: 1, + groupId: 1, + platform: 'linux', + machineId: 1, + }) + sinon.stub(electron.app, 'on').withArgs('ready').yieldsAsync() sinon.stub(browsers, 'open') sinon.stub(runMode, 'waitForSocketConnection').resolves() + + sinon.stub(runMode, 'waitForBrowserToConnect').resolves({ + stats: { + tests: 1, + passes: 2, + failures: 3, + pending: 4, + skipped: 5, + wallClockDuration: 6, + }, + tests: [], + hooks: [], + video: 'path/to/video', + shouldUploadVideo: true, + screenshots: [], + config: {}, + spec: {}, + }) + sinon.stub(runMode, 'waitForTestsToFinishRunning').resolves({ stats: { tests: 1, @@ -1335,6 +1384,33 @@ describe('lib/cypress', () => { }) }) + beforeEach(() => { + browsers.open.restore() + + const ee = mockEE() + + sinon.stub(launch, 'launch').returns(ee) + sinon.stub(Windows, 'create').returns(ee) + }) + + it('does not truncate a really long dashboard url', function () { + api.createRun.resolves({ + warnings: [], + runUrl: `http://dashboard.cypress.io/this-is-a${'-long'.repeat(50)}-url`, + }) + + return cypress.start([ + `--run-project=${this.recordPath}`, + '--record', + '--key=token-123', + '--group=electron-smoke-tests', + '--ciBuildId=ciBuildId123', + ]) + .then(() => { + return snapshotConsoleLogs('Long Dashboard URL') + }) + }) + it('errors and exits when group name is not unique and explicitly passed ciBuildId', function () { const err = new Error() diff --git a/packages/server/test/scripts/run.js b/packages/server/test/scripts/run.js index 0500a100b1f..1ccdd5216c5 100644 --- a/packages/server/test/scripts/run.js +++ b/packages/server/test/scripts/run.js @@ -20,10 +20,7 @@ if (run[0] && run[0].includes('--inspect-brk')) { if (options['glob-in-dir']) { if (run[0]) { - run = [ - path.join(options['glob-in-dir'], '**', `*${run[0]}*`), - path.join(options['glob-in-dir'], `*${run[0]}*`), - ] + run = [path.join(options['glob-in-dir'], '**', `*${run[0]}*`)] } else { run = [path.join(options['glob-in-dir'], '**')] } @@ -55,7 +52,7 @@ if (!run || !run.length) { $ yarn test-unit $ yarn test-integration - $ yarn test-e2e + $ yarn test-performance `) } diff --git a/system-tests/README.md b/system-tests/README.md index e2af257276b..f17dcf2b424 100644 --- a/system-tests/README.md +++ b/system-tests/README.md @@ -10,22 +10,23 @@ These tests run in CI in Electron, Chrome, and Firefox under the `system-tests` ## Running System Tests ```bash -yarn test -yarn test test/async_timeouts_spec.js -## or -yarn test async_timeouts ## shorthand, uses globbing to find spec +yarn test # runs all tests +## or use globbing to find spec in folders as defined in "glob-in-dir" param in package.json +yarn test screenshot*element # runs screenshot_element_capture_spec.js +yarn test screenshot # runs screenshot_element_capture_spec.js, screenshot_fullpage_capture_spec.js, ..., etc. + ``` To keep the browser open after a spec run (for easier debugging and iterating on specs), you can pass the `--no-exit` flag to the test command. Live reloading due to spec changes should also work: ```sh -yarn test test/go_spec.js --browser chrome --no-exit +yarn test go_spec.js --browser chrome --no-exit ``` To debug the Cypress process under test, you can pass `--cypress-inspect-brk`: ```sh -yarn test test/go_spec.js --browser chrome --no-exit --cypress-inspect-brk +yarn test go_spec.js --browser chrome --no-exit --cypress-inspect-brk ``` ## Developing Tests diff --git a/system-tests/__snapshots__/record_spec.js b/system-tests/__snapshots__/record_spec.js index 256e2c592e8..7205428d081 100644 --- a/system-tests/__snapshots__/record_spec.js +++ b/system-tests/__snapshots__/record_spec.js @@ -251,7 +251,7 @@ We dynamically generated a new test to display this failure. ─────────────────────────────────────────────────────────────────────────────────────────────────────── - Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 + Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 ` @@ -348,7 +348,7 @@ StatusCodeError: 500 - "Internal Server Error" ─────────────────────────────────────────────────────────────────────────────────────────────────────── - Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 + Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 ` @@ -462,7 +462,7 @@ exports['e2e record video recording does not upload when not enabled 1'] = ` ─────────────────────────────────────────────────────────────────────────────────────────────────────── - Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 + Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 ` @@ -544,7 +544,7 @@ exports['e2e record api interaction errors uploading assets warns but proceeds 1 ─────────────────────────────────────────────────────────────────────────────────────────────────────── - Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 + Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 ` @@ -698,7 +698,7 @@ exports['e2e record parallelization passes in parallel with group 1'] = ` ─────────────────────────────────────────────────────────────────────────────────────────────────────── - Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 + Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 ` @@ -913,7 +913,7 @@ We dynamically generated a new test to display this failure. ─────────────────────────────────────────────────────────────────────────────────────────────────────── - Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 + Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 ` @@ -1159,7 +1159,7 @@ StatusCodeError: 500 - "Internal Server Error" ─────────────────────────────────────────────────────────────────────────────────────────────────────── - Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 + Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 ` @@ -1361,7 +1361,7 @@ https://on.cypress.io/dashboard/organizations/org-id-1234/billing ─────────────────────────────────────────────────────────────────────────────────────────────────────── - Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 + Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 ` @@ -1441,7 +1441,7 @@ https://on.cypress.io/dashboard/organizations/org-id-1234/billing ─────────────────────────────────────────────────────────────────────────────────────────────────────── - Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 + Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 ` @@ -1526,7 +1526,7 @@ Details: ─────────────────────────────────────────────────────────────────────────────────────────────────────── - Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 + Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 ` @@ -1862,7 +1862,7 @@ https://on.cypress.io/dashboard/organizations/org-id-1234/billing ─────────────────────────────────────────────────────────────────────────────────────────────────────── - Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 + Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 ` @@ -1944,7 +1944,7 @@ https://on.cypress.io/dashboard/organizations/org-id-1234/billing ─────────────────────────────────────────────────────────────────────────────────────────────────────── - Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 + Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 ` @@ -2024,7 +2024,7 @@ https://on.cypress.io/dashboard/organizations/org-id-1234/billing ─────────────────────────────────────────────────────────────────────────────────────────────────────── - Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 + Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 ` @@ -2104,7 +2104,7 @@ https://on.cypress.io/dashboard/organizations/org-id-1234/billing ─────────────────────────────────────────────────────────────────────────────────────────────────────── - Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 + Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 ` @@ -2184,7 +2184,7 @@ https://on.cypress.io/dashboard/organizations/org-id-1234/billing ─────────────────────────────────────────────────────────────────────────────────────────────────────── - Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 + Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 ` @@ -2454,7 +2454,7 @@ exports['e2e record api skips specs records tests and exits without executing 1' ─────────────────────────────────────────────────────────────────────────────────────────────────────── - Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 + Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 Exiting with non-zero exit code because the run was canceled. @@ -2533,7 +2533,7 @@ exports['e2e record api skips specs records tests and exits without executing in ─────────────────────────────────────────────────────────────────────────────────────────────────────── - Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 + Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 Exiting with non-zero exit code because the run was canceled. @@ -2630,7 +2630,7 @@ exports['e2e record empty specs succeeds when empty spec file 1'] = ` ─────────────────────────────────────────────────────────────────────────────────────────────────────── - Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 + Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 ` @@ -2723,7 +2723,7 @@ exports['e2e record metadata sends Studio usage metadata 1'] = ` ─────────────────────────────────────────────────────────────────────────────────────────────────────── - Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 + Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 ` diff --git a/system-tests/package.json b/system-tests/package.json index 92a6bde243e..a2337e47ff4 100644 --- a/system-tests/package.json +++ b/system-tests/package.json @@ -10,7 +10,7 @@ "clean-deps": "find . -depth -name node_modules -type d -exec rimraf {} \\;", "preprojects:yarn:install": "yarn clean-deps", "projects:yarn:install": "node ./scripts/projects-yarn-install.js", - "test": "node ./scripts/run.js --glob-in-dir='{test,test-binary}'", + "test": "node ./scripts/run.js --glob-in-dir={test,test-binary}", "test:ci": "node ./scripts/run.js", "update:snapshots": "SNAPSHOT_UPDATE=1 npm run test" },