From 526b8f016656c5a1bf9488f46c9721a025c00e34 Mon Sep 17 00:00:00 2001 From: "cypress-bot[bot]" <+cypress-bot[bot]@users.noreply.github.com> Date: Sun, 19 Feb 2023 01:07:21 +0000 Subject: [PATCH 1/9] chore: updating v8 snapshot cache --- tooling/v8-snapshot/cache/win32/snapshot-meta.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/tooling/v8-snapshot/cache/win32/snapshot-meta.json b/tooling/v8-snapshot/cache/win32/snapshot-meta.json index 28bfb386244..ba7ff953c9a 100644 --- a/tooling/v8-snapshot/cache/win32/snapshot-meta.json +++ b/tooling/v8-snapshot/cache/win32/snapshot-meta.json @@ -151,8 +151,6 @@ "./node_modules/@cypress/commit-info/node_modules/semver/semver.js", "./node_modules/@cypress/get-windows-proxy/node_modules/debug/src/browser.js", "./node_modules/@cypress/get-windows-proxy/node_modules/debug/src/index.js", - "./node_modules/@cypress/get-windows-proxy/node_modules/registry-js/dist/lib/index.js", - "./node_modules/@cypress/get-windows-proxy/node_modules/registry-js/dist/lib/registry.js", "./node_modules/@cypress/request-promise/lib/rp.js", "./node_modules/@cypress/request/index.js", "./node_modules/@cypress/request/lib/helpers.js", From 2eed9637931b2e55d6b1853fc434d793a07ab38a Mon Sep 17 00:00:00 2001 From: "cypress-bot[bot]" <+cypress-bot[bot]@users.noreply.github.com> Date: Tue, 21 Feb 2023 01:00:40 +0000 Subject: [PATCH 2/9] chore: updating v8 snapshot cache --- .circleci/workflows.yml | 2 +- cli/CHANGELOG.md | 1 + npm/webpack-dev-server/CHANGELOG.md | 7 ++ .../cypress/e2e/webpack-dev-server.cy.ts | 18 ++++ .../src/CypressCTWebpackPlugin.ts | 21 ++-- .../src/makeDefaultWebpackConfig.ts | 1 + .../test/devServer-e2e.spec.ts | 8 +- .../e2e/e2e/origin/cookie_behavior.cy.ts | 92 ++++------------- .../driver/src/cross-origin/events/cookies.ts | 26 +++-- packages/driver/types/internal-types.d.ts | 4 +- packages/proxy/lib/http/index.ts | 5 +- packages/proxy/lib/http/util/cookies.ts | 4 +- packages/proxy/lib/http/util/inject.ts | 4 +- packages/proxy/lib/http/util/rewriter.ts | 4 +- packages/runner/injection/patches/cookies.ts | 12 +-- packages/server/lib/automation/automation.ts | 8 +- packages/server/lib/automation/cookies.ts | 98 +++++++++++-------- packages/server/lib/server-base.ts | 5 +- packages/server/lib/socket-base.ts | 4 +- packages/server/lib/util/cookies.ts | 20 +++- ...-webpack-dev-server-custom-index.config.ts | 10 ++ .../react/my-component-index.html | 12 +++ 22 files changed, 203 insertions(+), 163 deletions(-) create mode 100644 system-tests/project-fixtures/react/cypress-webpack-dev-server-custom-index.config.ts create mode 100644 system-tests/project-fixtures/react/my-component-index.html diff --git a/.circleci/workflows.yml b/.circleci/workflows.yml index 9ce01cc70d7..fd0647ddc69 100644 --- a/.circleci/workflows.yml +++ b/.circleci/workflows.yml @@ -134,7 +134,7 @@ commands: - run: name: Check current branch to persist artifacts command: | - if [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "release/"* && "$CIRCLE_BRANCH" != "fix-duplicate-and-expired-cookies" ]]; then + if [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "release/"* && "$CIRCLE_BRANCH" != "astone123/ventura-webpack-permission-testing" ]]; then echo "Not uploading artifacts or posting install comment for this branch." circleci-agent step halt fi diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index 6b42b6c4816..8c9b11482da 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -10,6 +10,7 @@ _Released 03/1/2023 (PENDING)_ **Bugfixes:** - Fixed an issue where cookies were being duplicated with the same hostname, but a prepended dot. Fixed an issue where cookies may not be expiring correctly. Fixes [#25174](https://github.com/cypress-io/cypress/issues/25174), [#25205](https://github.com/cypress-io/cypress/issues/25205) and [#25495](https://github.com/cypress-io/cypress/issues/25495). +- Fixed an issue where cookies weren't being synced when the application was stable. Fixed in [#25855](https://github.com/cypress-io/cypress/pull/25855). Fixes [#25835](https://github.com/cypress-io/cypress/issues/25835). - Added missing TypeScript type definitions for the [`cy.reload()`](https://docs.cypress.io/api/commands/reload) command. Addressed in [#25779](https://github.com/cypress-io/cypress/pull/25779). - Ensure Angular components are mounted inside the correct element. Fixes [#24385](https://github.com/cypress-io/cypress/issues/24385) - Fix a bug where files outside the project root in a monorepo are not correctly served when using Vite. Addressed in [#25801](https://github.com/cypress-io/cypress/pull/25801) diff --git a/npm/webpack-dev-server/CHANGELOG.md b/npm/webpack-dev-server/CHANGELOG.md index 9b09eaa932c..f84206558cd 100644 --- a/npm/webpack-dev-server/CHANGELOG.md +++ b/npm/webpack-dev-server/CHANGELOG.md @@ -1,3 +1,10 @@ +# [@cypress/webpack-dev-server-v3.2.4](https://github.com/cypress-io/cypress/compare/@cypress/webpack-dev-server-v3.2.3...@cypress/webpack-dev-server-v3.2.4) (2023-02-20) + + +### Bug Fixes + +* **webpack-dev-server:** touch component-index during onSpecsChange to avoid writing to app file ([#25861](https://github.com/cypress-io/cypress/issues/25861)) ([87816de](https://github.com/cypress-io/cypress/commit/87816de1b7c4c3873ad791d71ac2af5aaa88e889)) + # [@cypress/webpack-dev-server-v3.2.3](https://github.com/cypress-io/cypress/compare/@cypress/webpack-dev-server-v3.2.2...@cypress/webpack-dev-server-v3.2.3) (2023-01-24) diff --git a/npm/webpack-dev-server/cypress/e2e/webpack-dev-server.cy.ts b/npm/webpack-dev-server/cypress/e2e/webpack-dev-server.cy.ts index 4f587e24b6f..06e85369ea8 100644 --- a/npm/webpack-dev-server/cypress/e2e/webpack-dev-server.cy.ts +++ b/npm/webpack-dev-server/cypress/e2e/webpack-dev-server.cy.ts @@ -39,4 +39,22 @@ describe('Config options', () => { expect(verifyFile).to.eq('OK') }) }) + + it('recompiles with new spec and custom indexHtmlFile', () => { + cy.scaffoldProject('webpack5_wds4-react') + cy.openProject('webpack5_wds4-react', ['--config-file', 'cypress-webpack-dev-server-custom-index.config.ts']) + cy.startAppServer('component') + + cy.visitApp() + + cy.withCtx(async (ctx) => { + await ctx.actions.file.writeFileInProject( + ctx.path.join('src', 'New.cy.js'), + await ctx.file.readFileInProject(ctx.path.join('src', 'App.cy.jsx')), + ) + }) + + cy.contains('New.cy.js').click() + cy.waitForSpecToFinish({ passCount: 2 }) + }) }) diff --git a/npm/webpack-dev-server/src/CypressCTWebpackPlugin.ts b/npm/webpack-dev-server/src/CypressCTWebpackPlugin.ts index 8cb128b2bbc..9aef4e5aa67 100644 --- a/npm/webpack-dev-server/src/CypressCTWebpackPlugin.ts +++ b/npm/webpack-dev-server/src/CypressCTWebpackPlugin.ts @@ -13,6 +13,7 @@ export interface CypressCTWebpackPluginOptions { supportFile: string | false devServerEvents: EventEmitter webpack: Function + indexHtmlFile: string } export type CypressCTContextOptions = Omit @@ -47,6 +48,7 @@ export class CypressCTWebpackPlugin { private supportFile: string | false private compilation: Webpack45Compilation | null = null private webpack: Function + private indexHtmlFile: string private readonly projectRoot: string private readonly devServerEvents: EventEmitter @@ -57,6 +59,7 @@ export class CypressCTWebpackPlugin { this.projectRoot = options.projectRoot this.devServerEvents = options.devServerEvents this.webpack = options.webpack + this.indexHtmlFile = options.indexHtmlFile } private addLoaderContext = (loaderContext: object, module: any) => { @@ -64,6 +67,7 @@ export class CypressCTWebpackPlugin { files: this.files, projectRoot: this.projectRoot, supportFile: this.supportFile, + indexHtmlFile: this.indexHtmlFile, } }; @@ -93,11 +97,16 @@ export class CypressCTWebpackPlugin { } /* - * `webpack --watch` watches the existing specs and their dependencies for changes, - * but we also need to add additional dependencies to our dynamic "browser.js" (generated - * using loader.ts) when new specs are created. This hook informs webpack that browser.js - * has been "updated on disk", causing a recompliation (and pulling the new specs in as - * dependencies). + * `webpack --watch` watches the existing specs and their dependencies for changes. + * When new specs are created, we need to trigger a recompilation to add the new specs + * as dependencies. This hook informs webpack that `component-index.html` has been "updated on disk", + * causing a recompilation (and pulling the new specs in as dependencies). We use the component + * index file because we know that it will be there since the project is using Component Testing. + * + * We were using `browser.js` before to cause a recompilation but we ran into an + * issue with MacOS Ventura that will not allow us to write to files inside of our application bundle. + * + * See https://github.com/cypress-io/cypress/issues/24398 */ private onSpecsChange = async (specs: Cypress.Cypress['spec'][]) => { if (!this.compilation || _.isEqual(specs, this.files)) { @@ -110,7 +119,7 @@ export class CypressCTWebpackPlugin { // eslint-disable-next-line no-restricted-syntax const utimesSync: UtimesSync = inputFileSystem.fileSystem.utimesSync ?? fs.utimesSync - utimesSync(path.resolve(__dirname, 'browser.js'), new Date(), new Date()) + utimesSync(path.join(this.projectRoot, this.indexHtmlFile), new Date(), new Date()) } /** diff --git a/npm/webpack-dev-server/src/makeDefaultWebpackConfig.ts b/npm/webpack-dev-server/src/makeDefaultWebpackConfig.ts index 0c3e1dbacfa..e251968c59b 100644 --- a/npm/webpack-dev-server/src/makeDefaultWebpackConfig.ts +++ b/npm/webpack-dev-server/src/makeDefaultWebpackConfig.ts @@ -89,6 +89,7 @@ export function makeCypressWebpackConfig ( devServerEvents, supportFile, webpack, + indexHtmlFile, }), ], devtool: 'inline-source-map', diff --git a/npm/webpack-dev-server/test/devServer-e2e.spec.ts b/npm/webpack-dev-server/test/devServer-e2e.spec.ts index 42f3a621374..4ab871743c3 100644 --- a/npm/webpack-dev-server/test/devServer-e2e.spec.ts +++ b/npm/webpack-dev-server/test/devServer-e2e.spec.ts @@ -68,7 +68,7 @@ const cypressConfig = { supportFile: '', isTextTerminal: true, devServerPublicPathRoute: root, - indexHtmlFile: path.join(__dirname, 'component-index.html'), + indexHtmlFile: 'test/component-index.html', } as any as Cypress.PluginConfigOptions describe('#devServer', () => { @@ -170,7 +170,7 @@ describe('#devServer', () => { await closeServer(close) }) - it('touches browser.js when a spec file is added and recompile', async function () { + it('touches component index when a spec file is added and recompile', async function () { // File watching only enabled when running in `open` mode cypressConfig.isTextTerminal = false const devServerEvents = new EventEmitter() @@ -187,13 +187,13 @@ describe('#devServer', () => { absolute: `${root}/test/fixtures/bar.spec.js`, } - const oldmtime = fs.statSync('./dist/browser.js').mtimeMs + const oldmtime = fs.statSync(cypressConfig.indexHtmlFile).mtimeMs await once(devServerEvents, 'dev-server:compile:success') devServerEvents.emit('dev-server:specs:changed', [newSpec]) await once(devServerEvents, 'dev-server:compile:success') - const updatedmtime = fs.statSync('./dist/browser.js').mtimeMs + const updatedmtime = fs.statSync(cypressConfig.indexHtmlFile).mtimeMs expect(oldmtime).to.not.equal(updatedmtime) diff --git a/packages/driver/cypress/e2e/e2e/origin/cookie_behavior.cy.ts b/packages/driver/cypress/e2e/e2e/origin/cookie_behavior.cy.ts index 6e0965aada6..626e4f8a3a5 100644 --- a/packages/driver/cypress/e2e/e2e/origin/cookie_behavior.cy.ts +++ b/packages/driver/cypress/e2e/e2e/origin/cookie_behavior.cy.ts @@ -251,17 +251,7 @@ describe('Cookie Behavior', { browser: '!webkit' }, () => { // though request is cross origin, site should have access directly to cookie because it is same site // assert cookie value is actually set in the browser - // current expected assertion. NOTE: This SHOULD be consistent - if (Cypress.isBrowser('firefox')) { - // firefox actually sets the cookie correctly - cy.getCookie('foo1').its('value').should('equal', 'bar1') - } else { - cy.getCookie('foo1').should('equal', null) - } - - // FIXME: Ideally, browser should have access to this cookie. Should be fixed in https://github.com/cypress-io/cypress/pull/23643. - // future expected assertion - // cy.getCookie('foo1').its('value').should('equal', 'bar1') + cy.getCookie('foo1').its('value').should('equal', 'bar1') cy.window().then((win) => { // but send the cookies in the request @@ -298,17 +288,7 @@ describe('Cookie Behavior', { browser: '!webkit' }, () => { // though request is cross origin, site should have access directly to cookie because it is same site // assert cookie value is actually set in the browser - // current expected assertion. NOTE: This SHOULD be consistent - if (Cypress.isBrowser('firefox')) { - // firefox actually sets the cookie correctly - cy.getCookie('foo1').its('value').should('equal', 'bar1') - } else { - cy.getCookie('foo1').should('equal', null) - } - - // FIXME: Ideally, browser should have access to this cookie. Should be fixed in https://github.com/cypress-io/cypress/pull/23643. - // future expected assertion - // cy.getCookie('foo1').its('value').should('equal', 'bar1') + cy.getCookie('foo1').its('value').should('equal', 'bar1') cy.window().then((win) => { // but send the cookies in the request @@ -376,17 +356,7 @@ describe('Cookie Behavior', { browser: '!webkit' }, () => { }) // assert cookie value is actually set in the browser - // current expected assertion. - if (Cypress.isBrowser('firefox')) { - // firefox actually sets the cookie correctly - cy.getCookie('foo1').its('value').should('equal', 'bar1') - } else { - cy.getCookie('foo1').should('equal', null) - } - - // FIXME: Ideally, browser should have access to this cookie. Should be fixed in https://github.com/cypress-io/cypress/pull/23643. - // future expected assertion - // cy.getCookie('foo1').its('value').should('equal', 'bar1') + cy.getCookie('foo1').its('value').should('equal', 'bar1') cy.window().then((win) => { return cy.wrap(window.makeRequest(win, `${scheme}://app.foobar.com:${crossOriginPort}/test-request-credentials`, 'fetch', 'include')) @@ -418,17 +388,7 @@ describe('Cookie Behavior', { browser: '!webkit' }, () => { }) // assert cookie value is actually set in the browser - // current expected assertion. NOTE: This SHOULD be consistent - if (Cypress.isBrowser('firefox')) { - // firefox actually sets the cookie correctly - cy.getCookie('foo1').its('value').should('equal', 'bar1') - } else { - cy.getCookie('foo1').should('equal', null) - } - - // FIXME: Ideally, browser should have access to this cookie. Should be fixed in https://github.com/cypress-io/cypress/pull/23643. - // future expected assertion - // cy.getCookie('foo1').its('value').should('equal', 'bar1') + cy.getCookie('foo1').its('value').should('equal', 'bar1') cy.window().then((win) => { return cy.wrap(window.makeRequest(win, `${scheme}://app.foobar.com:${crossOriginPort}/test-request-credentials`, 'fetch')) @@ -529,14 +489,11 @@ describe('Cookie Behavior', { browser: '!webkit' }, () => { return cy.wrap(window.makeRequest(win, `${scheme}://www.barbaz.com:${sameOriginPort}/set-cookie-credentials?cookie=bar1=baz1; Domain=barbaz.com; SameSite=None; Secure`, 'xmlHttpRequest', true)) }) - // assert cookie value is actually set in the browser if (scheme === 'https') { - // FIXME: cy.getCookie does not believe this cookie exists. Should be fixed in https://github.com/cypress-io/cypress/pull/23643. - cy.getCookie('bar1').should('equal', null) - // can only set third-party SameSite=None with Secure attribute, which is only possibly over https - - //expected future assertion - // cy.getCookie('bar1').its('value').should('equal', 'baz1') + // assert cookie value is actually set in the browser, even if in a different domain + cy.getCookie('bar1', { + domain: 'barbaz.com', + }).its('value').should('equal', 'baz1') } else { cy.getCookie('bar1').should('equal', null) } @@ -572,12 +529,10 @@ describe('Cookie Behavior', { browser: '!webkit' }, () => { return cy.wrap(window.makeRequest(win, `${scheme}://www.barbaz.com:${sameOriginPort}/set-cookie-credentials?cookie=bar1=baz1; Domain=barbaz.com; SameSite=None; Secure`, 'xmlHttpRequest', true)) }) - // FIXME: cy.getCookie does not believe this cookie exists. Should be fixed in https://github.com/cypress-io/cypress/pull/23643. - cy.getCookie('bar1').should('equal', null) - // can only set third-party SameSite=None with Secure attribute, which is only possibly over https - - //expected future assertion - // cy.getCookie('bar1').its('value').should('equal', 'baz1') + // assert cookie value is actually set in the browser, even if in a different domain + cy.getCookie('bar1', { + domain: 'barbaz.com', + }).its('value').should('equal', 'baz1') cy.window().then((win) => { return cy.wrap(window.makeRequest(win, `${scheme}://www.barbaz.com:${sameOriginPort}/test-request-credentials`, 'xmlHttpRequest', true)) @@ -649,14 +604,11 @@ describe('Cookie Behavior', { browser: '!webkit' }, () => { return cy.wrap(window.makeRequest(win, `${scheme}://www.barbaz.com:${sameOriginPort}/set-cookie-credentials?cookie=bar1=baz1; Domain=barbaz.com; SameSite=None; Secure`, 'fetch', 'include')) }) - // assert cookie value is actually set in the browser if (scheme === 'https') { - // FIXME: cy.getCookie does not believe this cookie exists. Should be fixed in https://github.com/cypress-io/cypress/pull/23643. - cy.getCookie('bar1').should('equal', null) - // can only set third-party SameSite=None with Secure attribute, which is only possibly over https - - //expected future assertion - // cy.getCookie('bar1').its('value').should('equal', 'baz1') + // assert cookie value is actually set in the browser, even if in a different domain + cy.getCookie('bar1', { + domain: 'barbaz.com', + }).its('value').should('equal', 'baz1') } else { cy.getCookie('bar1').should('equal', null) } @@ -695,14 +647,10 @@ describe('Cookie Behavior', { browser: '!webkit' }, () => { return cy.wrap(window.makeRequest(win, `${scheme}://www.barbaz.com:${sameOriginPort}/set-cookie-credentials?cookie=bar1=baz1; Domain=barbaz.com; SameSite=None; Secure`, 'fetch', 'include')) }) - // assert cookie value is actually set in the browser - - // FIXME: cy.getCookie does not believe this cookie exists, though it is set in the browser. Should be fixed in https://github.com/cypress-io/cypress/pull/23643. - cy.getCookie('bar1').should('equal', null) - // can only set third-party SameSite=None with Secure attribute, which is only possibly over https - - //expected future assertion - // cy.getCookie('bar1').its('value').should('equal', 'baz1') + // assert cookie value is actually set in the browser, even if in a different domain + cy.getCookie('bar1', { + domain: 'barbaz.com', + }).its('value').should('equal', 'baz1') cy.window().then((win) => { return cy.wrap(window.makeRequest(win, `${scheme}://www.barbaz.com:${sameOriginPort}/test-request-credentials`, 'fetch', 'include')) diff --git a/packages/driver/src/cross-origin/events/cookies.ts b/packages/driver/src/cross-origin/events/cookies.ts index ed8303a65bd..655d6d28c76 100644 --- a/packages/driver/src/cross-origin/events/cookies.ts +++ b/packages/driver/src/cross-origin/events/cookies.ts @@ -1,4 +1,4 @@ -import type { AutomationCookie } from '@packages/server/lib/automation/cookies' +import type { SerializableAutomationCookie } from '@packages/server/lib/util/cookies' import type { ICypress } from '../../cypress' // cross-origin cookies collected by the the proxy are sent down to the driver @@ -10,10 +10,10 @@ export const handleCrossOriginCookies = (Cypress: ICypress) => { // multiple requests could set cookies while the page is loading, so we // collect all cookies and only send set them via automation once after // the page has loaded - let cookiesToSend: AutomationCookie[] = [] + let cookiesToSend: SerializableAutomationCookie[] = [] let waitingToSend = false - Cypress.on('cross:origin:cookies', (cookies: AutomationCookie[]) => { + Cypress.on('cross:origin:cookies', (cookies: SerializableAutomationCookie[]) => { cookiesToSend = cookiesToSend.concat(cookies) Cypress.backend('cross:origin:cookies:received') @@ -22,11 +22,7 @@ export const handleCrossOriginCookies = (Cypress: ICypress) => { waitingToSend = true - // this event allows running a handler before stability is released. - // this prevents subsequent commands from running until the cookies - // are set via automation - // @ts-ignore - Cypress.once('before:stability:release', () => { + const syncCookiesViaAutomation = () => { const cookies = cookiesToSend cookiesToSend = [] @@ -37,6 +33,18 @@ export const handleCrossOriginCookies = (Cypress: ICypress) => { .catch(() => { // errors here can be ignored as they're not user-actionable }) - }) + } + + // if the application is already stable, sync the cookies to the automation client immediately + if (cy.state('isStable')) { + syncCookiesViaAutomation() + } else { + // otherwise, wait until stability is achieved + // this event allows running a handler before stability is released. + // this prevents subsequent commands from running until the cookies + // are set via automation + // @ts-ignore + Cypress.once('before:stability:release', syncCookiesViaAutomation) + } }) } diff --git a/packages/driver/types/internal-types.d.ts b/packages/driver/types/internal-types.d.ts index e5cc171c170..7ebafc77c59 100644 --- a/packages/driver/types/internal-types.d.ts +++ b/packages/driver/types/internal-types.d.ts @@ -53,10 +53,10 @@ declare namespace Cypress { } interface Actions { - (action: 'set:cookie', fn: (cookie: AutomationCookie) => void) + (action: 'set:cookie', fn: (cookie: SerializableAutomationCookie) => void) (action: 'clear:cookie', fn: (name: string) => void) (action: 'clear:cookies', fn: () => void) - (action: 'cross:origin:cookies', fn: (cookies: AutomationCookie[]) => void) + (action: 'cross:origin:cookies', fn: (cookies: SerializableAutomationCookie[]) => void) (action: 'before:stability:release', fn: () => void) (action: 'paused', fn: (nextCommandName: string) => void) } diff --git a/packages/proxy/lib/http/index.ts b/packages/proxy/lib/http/index.ts index 87448976c8f..f4c50493494 100644 --- a/packages/proxy/lib/http/index.ts +++ b/packages/proxy/lib/http/index.ts @@ -20,9 +20,8 @@ import RequestMiddleware from './request-middleware' import ResponseMiddleware from './response-middleware' import { DeferredSourceMapCache } from '@packages/rewriter' import type { RemoteStates } from '@packages/server/lib/remote_states' -import type { CookieJar } from '@packages/server/lib/util/cookies' +import type { CookieJar, SerializableAutomationCookie } from '@packages/server/lib/util/cookies' import type { RequestedWithAndCredentialManager } from '@packages/server/lib/util/requestedWithAndCredentialManager' -import type { AutomationCookie } from '@packages/server/lib/automation/cookies' import { errorUtils } from '@packages/errors' function getRandomColorFn () { @@ -59,7 +58,7 @@ type HttpMiddlewareCtx = { getPreRequest: (cb: GetPreRequestCb) => void getAUTUrl: Http['getAUTUrl'] setAUTUrl: Http['setAUTUrl'] - simulatedCookies: AutomationCookie[] + simulatedCookies: SerializableAutomationCookie[] } & T export const defaultMiddleware = { diff --git a/packages/proxy/lib/http/util/cookies.ts b/packages/proxy/lib/http/util/cookies.ts index a320a7b570c..c51bb5ce41d 100644 --- a/packages/proxy/lib/http/util/cookies.ts +++ b/packages/proxy/lib/http/util/cookies.ts @@ -3,7 +3,7 @@ import type Debug from 'debug' import { URL } from 'url' import { cors } from '@packages/network' import { urlOriginsMatch, urlSameSiteMatch } from '@packages/network/lib/cors' -import { AutomationCookie, Cookie, CookieJar, toughCookieToAutomationCookie } from '@packages/server/lib/util/cookies' +import { SerializableAutomationCookie, Cookie, CookieJar, toughCookieToAutomationCookie } from '@packages/server/lib/util/cookies' import type { RequestCredentialLevel, RequestedWithHeader } from '../../types' type SiteContext = 'same-origin' | 'same-site' | 'cross-site' @@ -197,7 +197,7 @@ export class CookiesHelper { const afterCookies = this.cookieJar.getAllCookies() - return afterCookies.reduce((memo, afterCookie) => { + return afterCookies.reduce((memo, afterCookie) => { if (matchesPreviousCookie(this.previousCookies, afterCookie)) return memo return memo.concat(toughCookieToAutomationCookie(afterCookie, this.defaultDomain)) diff --git a/packages/proxy/lib/http/util/inject.ts b/packages/proxy/lib/http/util/inject.ts index 830143173c6..936cf34eb37 100644 --- a/packages/proxy/lib/http/util/inject.ts +++ b/packages/proxy/lib/http/util/inject.ts @@ -1,6 +1,6 @@ import { oneLine } from 'common-tags' import { getRunnerInjectionContents, getRunnerCrossOriginInjectionContents } from '@packages/resolve-dist' -import type { AutomationCookie } from '@packages/server/lib/automation/cookies' +import type { SerializableAutomationCookie } from '@packages/server/lib/util/cookies' interface InjectionOpts { shouldInjectDocumentDomain: boolean @@ -8,7 +8,7 @@ interface InjectionOpts { interface FullCrossOriginOpts { modifyObstructiveThirdPartyCode: boolean modifyObstructiveCode: boolean - simulatedCookies: AutomationCookie[] + simulatedCookies: SerializableAutomationCookie[] } export function partial (domain, options: InjectionOpts) { diff --git a/packages/proxy/lib/http/util/rewriter.ts b/packages/proxy/lib/http/util/rewriter.ts index df6ab269b56..26067bce9e1 100644 --- a/packages/proxy/lib/http/util/rewriter.ts +++ b/packages/proxy/lib/http/util/rewriter.ts @@ -2,7 +2,7 @@ import * as inject from './inject' import * as astRewriter from './ast-rewriter' import * as regexRewriter from './regex-rewriter' import type { CypressWantsInjection } from '../../types' -import type { AutomationCookie } from '@packages/server/lib/automation/cookies' +import type { SerializableAutomationCookie } from '@packages/server/lib/util/cookies' export type SecurityOpts = { isNotJavascript?: boolean @@ -17,7 +17,7 @@ export type InjectionOpts = { domainName: string wantsInjection: CypressWantsInjection wantsSecurityRemoved: any - simulatedCookies: AutomationCookie[] + simulatedCookies: SerializableAutomationCookie[] shouldInjectDocumentDomain: boolean } diff --git a/packages/runner/injection/patches/cookies.ts b/packages/runner/injection/patches/cookies.ts index 586191311de..d4efd50260f 100644 --- a/packages/runner/injection/patches/cookies.ts +++ b/packages/runner/injection/patches/cookies.ts @@ -2,15 +2,15 @@ import { CookieJar, toughCookieToAutomationCookie, automationCookieToToughCookie, + SerializableAutomationCookie, } from '@packages/server/lib/util/cookies' import { Cookie as ToughCookie } from 'tough-cookie' -import type { AutomationCookie } from '@packages/server/lib/automation/cookies' function isHostOnlyCookie (domain) { return domain[0] !== '.' } -const parseDocumentCookieString = (documentCookieString: string): AutomationCookie[] => { +const parseDocumentCookieString = (documentCookieString: string): SerializableAutomationCookie[] => { if (!documentCookieString || !documentCookieString.trim().length) return [] return documentCookieString.split(';').map((cookieString) => { @@ -33,7 +33,7 @@ const parseDocumentCookieString = (documentCookieString: string): AutomationCook }) } -const sendCookieToServer = (cookie: AutomationCookie) => { +const sendCookieToServer = (cookie: SerializableAutomationCookie) => { window.top!.postMessage({ event: 'cross:origin:aut:set:cookie', data: { @@ -52,7 +52,7 @@ const sendCookieToServer = (cookie: AutomationCookie) => { // document.cookie runs into cross-origin restrictions when the AUT is on // a different origin than top. The goal is to make it act like it would // if the user's app was run in top. -export const patchDocumentCookie = (requestCookies: AutomationCookie[]) => { +export const patchDocumentCookie = (requestCookies: SerializableAutomationCookie[]) => { const url = location.href const domain = location.hostname const cookieJar = new CookieJar() @@ -64,7 +64,7 @@ export const patchDocumentCookie = (requestCookies: AutomationCookie[]) => { }).join('; ') } - const addCookies = (cookies: AutomationCookie[]) => { + const addCookies = (cookies: SerializableAutomationCookie[]) => { cookies.forEach((cookie) => { cookieJar.setCookie(automationCookieToToughCookie(cookie, domain), url, undefined) }) @@ -154,7 +154,7 @@ export const patchDocumentCookie = (requestCookies: AutomationCookie[]) => { // the following listeners are called from Cypress cookie commands, so that // the document.cookie value is updated optimistically - Cypress.on('set:cookie', (cookie: AutomationCookie) => { + Cypress.on('set:cookie', (cookie: SerializableAutomationCookie) => { setCookie(automationCookieToToughCookie(cookie, domain)) }) diff --git a/packages/server/lib/automation/automation.ts b/packages/server/lib/automation/automation.ts index 7651a2b9965..4033fe93ad2 100644 --- a/packages/server/lib/automation/automation.ts +++ b/packages/server/lib/automation/automation.ts @@ -38,8 +38,8 @@ export class Automation { this.middleware = this.initializeMiddleware() } - automationValve (message, fn) { - return (msg, data) => { + automationValve (message: string, fn: (...args: any) => any) { + return (msg: string, data: any) => { // enable us to omit message // argument if (!data) { @@ -60,7 +60,7 @@ export class Automation { } } - requestAutomationResponse (message, data, fn) { + requestAutomationResponse (message: string, data: any, fn: (...args: any) => any) { return new Bluebird((resolve, reject) => { const id = uuidv4() @@ -97,7 +97,7 @@ export class Automation { }) } - normalize (message, data, automate?) { + normalize (message: string, data: any, automate?) { return Bluebird.try(() => { switch (message) { case 'take:screenshot': diff --git a/packages/server/lib/automation/cookies.ts b/packages/server/lib/automation/cookies.ts index a1211d89d6c..be469a84395 100644 --- a/packages/server/lib/automation/cookies.ts +++ b/packages/server/lib/automation/cookies.ts @@ -2,13 +2,18 @@ import _ from 'lodash' import Debug from 'debug' import extension from '@packages/extension' import { isHostOnlyCookie } from '../browsers/cdp_automation' +import type { SerializableAutomationCookie } from '../util/cookies' + +type AutomationFn = (data: V) => Bluebird.Promise + +type AutomationMessageFn = (message: string, data: V) => Bluebird.Promise export interface AutomationCookie { domain: string - expiry: 'Infinity' | '-Infinity' | number | null + expirationDate?: number + expiry: number | null httpOnly: boolean - hostOnly: boolean - maxAge: 'Infinity' | '-Infinity' | number | null + hostOnly?: boolean name: string path: string | null sameSite: string @@ -19,49 +24,44 @@ export interface AutomationCookie { // match the w3c webdriver spec on return cookies // https://w3c.github.io/webdriver/webdriver-spec.html#cookies -const COOKIE_PROPERTIES = 'name value path domain secure httpOnly expiry hostOnly sameSite'.split(' ') +const COOKIE_PROPERTIES = 'domain expiry httpOnly hostOnly name path sameSite secure value'.split(' ') const debug = Debug('cypress:server:automation:cookies') -const normalizeCookies = (cookies) => { - return _.map(cookies, normalizeCookieProps) +const normalizeCookies = (cookies: (SerializableAutomationCookie | AutomationCookie)[]): AutomationCookie[] => { + return _.map(cookies, normalizeCookieProps) as AutomationCookie[] } -const normalizeCookieProps = function (props) { - if (!props) { - return props +const normalizeCookieProps = function (automationCookie: SerializableAutomationCookie | AutomationCookie | null) { + if (!automationCookie) { + return automationCookie } - // if the cookie is stored inside the server side cookie jar, - // we want to make the automation client aware so the domain property - // isn't mutated to prevent duplicate setting of cookies from different contexts. - // This should be handled by the hostOnly property - - const cookie = _.pick(props, COOKIE_PROPERTIES) + const cookie = _.pick(automationCookie, COOKIE_PROPERTIES) - if (props.expiry === '-Infinity') { + if (automationCookie.expiry === '-Infinity') { cookie.expiry = -Infinity // set the cookie to expired so when set, the cookie is removed cookie.expirationDate = 0 - } else if (props.expiry === 'Infinity') { + } else if (automationCookie.expiry === 'Infinity') { cookie.expiry = null - } else if (props.expiry != null) { + } else if (automationCookie.expiry != null) { // when sending cookie props we need to convert // expiry to expirationDate delete cookie.expiry - cookie.expirationDate = props.expiry - } else if (props.expirationDate != null) { + cookie.expirationDate = automationCookie.expiry + } else if (automationCookie.expirationDate != null) { // and when receiving cookie props we need to convert // expirationDate to expiry and always remove url delete cookie.expirationDate delete cookie.url - cookie.expiry = props.expirationDate + cookie.expiry = automationCookie.expirationDate } - return cookie + return cookie as AutomationCookie } -export const normalizeGetCookies = (cookies) => { +export const normalizeGetCookies = (cookies: (AutomationCookie | null)[]): (AutomationCookie | null)[] => { return _.chain(cookies) .map(normalizeGetCookieProps) // sort in order of expiration date, ascending @@ -69,7 +69,7 @@ export const normalizeGetCookies = (cookies) => { .value() } -export const normalizeGetCookieProps = (props) => { +export const normalizeGetCookieProps = (props: AutomationCookie | null) => { if (!props) { return props } @@ -91,7 +91,7 @@ export class Cookies { constructor (private cyNamespace, private cookieNamespace) {} - isNamespaced = (cookie) => { + isNamespaced = (cookie: AutomationCookie | null) => { const name = cookie && cookie.name // if the cookie has no name, return false @@ -108,13 +108,15 @@ export class Cookies { } } - getCookies (data, automate) { + getCookies (data: { + domain?: string + }, automate: AutomationMessageFn) { debug('getting:cookies %o', data) return automate('get:cookies', data) .then((cookies) => { cookies = normalizeGetCookies(cookies) - cookies = _.reject(cookies, (cookie) => this.isNamespaced(cookie)) + cookies = _.reject(cookies, (cookie) => this.isNamespaced(cookie)) as AutomationCookie[] debug('received get:cookies %o', cookies) @@ -122,7 +124,13 @@ export class Cookies { }) } - getCookie (data, automate) { + getCookie (data: { + domain: string + name: string + }, automate: AutomationFn<{ + domain: string + name: string + }, AutomationCookie | null>) { debug('getting:cookie %o', data) return automate(data) @@ -139,9 +147,9 @@ export class Cookies { }) } - setCookie (data, automate) { + setCookie (data: SerializableAutomationCookie, automate: AutomationFn) { this.throwIfNamespaced(data) - const cookie = normalizeCookieProps(data) + const cookie = normalizeCookieProps(data) as AutomationCookie // lets construct the url ourselves right now // unless we already have a URL @@ -160,13 +168,13 @@ export class Cookies { } setCookies ( - cookies: AutomationCookie[], - automate: (eventName: string, cookies: AutomationCookie[]) => Bluebird.Promise, + cookies: SerializableAutomationCookie[] | AutomationCookie[], + automate: AutomationMessageFn, eventName: 'set:cookies' | 'add:cookies' = 'set:cookies', ) { cookies = cookies.map((data) => { this.throwIfNamespaced(data) - const cookie = normalizeCookieProps(data) + const cookie = normalizeCookieProps(data) as AutomationCookie // lets construct the url ourselves right now // unless we already have a URL @@ -177,7 +185,7 @@ export class Cookies { debug(`${eventName} %o`, cookies) - return automate(eventName, cookies) + return automate(eventName, cookies as AutomationCookie[]) .return(cookies) } @@ -185,13 +193,19 @@ export class Cookies { // same as set:cookies in Firefox, but will only add cookies and not clear // them in Chrome, etc. addCookies ( - cookies: AutomationCookie[], - automate: (eventName: string, cookies: AutomationCookie[]) => Bluebird.Promise, + cookies: SerializableAutomationCookie[], + automate: AutomationMessageFn, ) { return this.setCookies(cookies, automate, 'add:cookies') } - clearCookie (data, automate) { + clearCookie (data: { + domain: string + name: string + }, automate: AutomationFn<{ + domain: string + name: string + }, AutomationCookie | null>) { this.throwIfNamespaced(data) debug('clear:cookie %o', data) @@ -205,7 +219,7 @@ export class Cookies { }) } - async clearCookies (data, automate) { + async clearCookies (data: AutomationCookie[], automate: AutomationMessageFn) { const cookiesToClear = data const cookies = _.reject(normalizeCookies(cookiesToClear), this.isNamespaced) @@ -216,8 +230,12 @@ export class Cookies { .mapSeries(normalizeCookieProps) } - changeCookie (data) { - const c = normalizeCookieProps(data.cookie) + changeCookie (data: { + cause: string + cookie: SerializableAutomationCookie + removed: boolean + }) { + const c = normalizeCookieProps(data.cookie) as AutomationCookie if (this.isNamespaced(c)) { return diff --git a/packages/server/lib/server-base.ts b/packages/server/lib/server-base.ts index 89d37c01174..8676881d952 100644 --- a/packages/server/lib/server-base.ts +++ b/packages/server/lib/server-base.ts @@ -32,8 +32,7 @@ import { createRoutesCT } from './routes-ct' import type { FoundSpec } from '@packages/types' import type { Server as WebSocketServer } from 'ws' import { RemoteStates } from './remote_states' -import { cookieJar } from './util/cookies' -import type { AutomationCookie } from './automation/cookies' +import { cookieJar, SerializableAutomationCookie } from './util/cookies' import { requestedWithAndCredentialManager, RequestedWithAndCredentialManager } from './util/requestedWithAndCredentialManager' const debug = Debug('cypress:server:server-base') @@ -182,7 +181,7 @@ export abstract class ServerBase { } setupCrossOriginRequestHandling () { - this._eventBus.on('cross:origin:cookies', (cookies: AutomationCookie[]) => { + this._eventBus.on('cross:origin:cookies', (cookies: SerializableAutomationCookie[]) => { this.socket.localBus.once('cross:origin:cookies:received', () => { this._eventBus.emit('cross:origin:cookies:received') }) diff --git a/packages/server/lib/socket-base.ts b/packages/server/lib/socket-base.ts index 0759bf788e6..0d82385e360 100644 --- a/packages/server/lib/socket-base.ts +++ b/packages/server/lib/socket-base.ts @@ -20,7 +20,7 @@ import { openFile, OpenFileDetails } from './util/file-opener' import open from './util/open' import type { DestroyableHttpServer } from './util/server_destroy' import * as session from './session' -import { AutomationCookie, cookieJar, SameSiteContext, automationCookieToToughCookie } from './util/cookies' +import { cookieJar, SameSiteContext, automationCookieToToughCookie, SerializableAutomationCookie } from './util/cookies' import runEvents from './plugins/run_events' // eslint-disable-next-line no-duplicate-imports @@ -390,7 +390,7 @@ export class SocketBase { }) }) - const setCrossOriginCookie = ({ cookie, url, sameSiteContext }: { cookie: AutomationCookie, url: string, sameSiteContext: SameSiteContext }) => { + const setCrossOriginCookie = ({ cookie, url, sameSiteContext }: { cookie: SerializableAutomationCookie, url: string, sameSiteContext: SameSiteContext }) => { const domain = cors.getOrigin(url) cookieJar.setCookie(automationCookieToToughCookie(cookie, domain), url, sameSiteContext) diff --git a/packages/server/lib/util/cookies.ts b/packages/server/lib/util/cookies.ts index f0f46c17138..8c31b1198af 100644 --- a/packages/server/lib/util/cookies.ts +++ b/packages/server/lib/util/cookies.ts @@ -1,7 +1,12 @@ import { Cookie, CookieJar as ToughCookieJar } from 'tough-cookie' import type { AutomationCookie } from '../automation/cookies' -export { AutomationCookie, Cookie } +interface SerializableAutomationCookie extends Omit { + expiry: 'Infinity' | '-Infinity' | number | null + maxAge: 'Infinity' | '-Infinity' | number | null +} + +export { SerializableAutomationCookie, Cookie } interface CookieData { name: string @@ -11,12 +16,15 @@ interface CookieData { export type SameSiteContext = 'strict' | 'lax' | 'none' | undefined -export const toughCookieToAutomationCookie = (toughCookie: Cookie, defaultDomain: string): AutomationCookie => { +export const toughCookieToAutomationCookie = (toughCookie: Cookie, defaultDomain: string): SerializableAutomationCookie => { + // tough-cookie is smart enough to determine the expiryTime based on maxAge and expiry + // meaning the expiry property should be a catch all for determining expiry time const expiry = toughCookie.expiryTime() return { domain: toughCookie.domain || defaultDomain, - // if expiry is Infinity or -Infinity, this operation is a no-op + // cast Infinity/-Infinity to a string to make sure the data is serialized through the automation client. + // cookie normalization in the automation client will cast this back to Infinity/-Infinity expiry: (expiry === Infinity || expiry === -Infinity) ? expiry.toString() as '-Infinity' | 'Infinity' : expiry / 1000, httpOnly: toughCookie.httpOnly, // we want to make sure the hostOnly property is respected when syncing with CDP/extension to prevent duplicates @@ -30,16 +38,18 @@ export const toughCookieToAutomationCookie = (toughCookie: Cookie, defaultDomain } } -export const automationCookieToToughCookie = (automationCookie: AutomationCookie, defaultDomain: string): Cookie => { +export const automationCookieToToughCookie = (automationCookie: SerializableAutomationCookie, defaultDomain: string): Cookie => { let expiry: Date | undefined = undefined if (automationCookie.expiry != null) { if (isFinite(automationCookie.expiry as number)) { expiry = new Date(automationCookie.expiry as number * 1000) - } else if (automationCookie.expiry === '-Infinity') { + } else if (automationCookie.expiry === '-Infinity' || automationCookie.expiry === -Infinity) { // if negative Infinity, the cookie is Date(0), has expired and is slated to be removed expiry = new Date(0) } + // if Infinity is set on the automation client, the expiry doesn't get set, meaning the no-op + // accomplishes an Infinite expire time } return new Cookie({ diff --git a/system-tests/project-fixtures/react/cypress-webpack-dev-server-custom-index.config.ts b/system-tests/project-fixtures/react/cypress-webpack-dev-server-custom-index.config.ts new file mode 100644 index 00000000000..c4efc3bcf79 --- /dev/null +++ b/system-tests/project-fixtures/react/cypress-webpack-dev-server-custom-index.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from 'cypress' +import defaultConfig from './cypress-webpack.config' + +export default defineConfig({ + ...defaultConfig, + component: { + ...defaultConfig.component as Cypress.Config['component'], + indexHtmlFile: 'my-component-index.html', + }, +}) diff --git a/system-tests/project-fixtures/react/my-component-index.html b/system-tests/project-fixtures/react/my-component-index.html new file mode 100644 index 00000000000..ac6e79fd83d --- /dev/null +++ b/system-tests/project-fixtures/react/my-component-index.html @@ -0,0 +1,12 @@ + + + + + + + Codestin Search App + + +
+ + \ No newline at end of file From 0b9eac8ca2c1ffcf936f87519d82e69768b10f64 Mon Sep 17 00:00:00 2001 From: "cypress-bot[bot]" <+cypress-bot[bot]@users.noreply.github.com> Date: Wed, 22 Feb 2023 02:11:21 +0000 Subject: [PATCH 3/9] chore: updating v8 snapshot cache --- .../workflows/triage_add_to_routed_project.yml | 9 +++++++-- .../workflows/triage_closed_issue_comment.yml | 11 ++++++++--- .../v8-snapshot/cache/linux/snapshot-meta.json | 16 +++++++++++++--- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/.github/workflows/triage_add_to_routed_project.yml b/.github/workflows/triage_add_to_routed_project.yml index 6bb13d85fa3..c50f4233cc2 100644 --- a/.github/workflows/triage_add_to_routed_project.yml +++ b/.github/workflows/triage_add_to_routed_project.yml @@ -1,5 +1,10 @@ name: 'Triage: route to team project board' on: +# makes this workflow reusable + workflow_call: + secrets: + ADD_TO_TRIAGE_BOARD_TOKEN: + required: true issues: types: - labeled @@ -10,7 +15,7 @@ jobs: steps: - name: Get project data env: - GITHUB_TOKEN: ${{ secrets.ADD_TO_PROJECT_TOKEN }} + GITHUB_TOKEN: ${{ secrets.ADD_TO_TRIAGE_BOARD_TOKEN }} ORGANIZATION: 'cypress-io' PROJECT_NUMBER: 10 run: | @@ -26,7 +31,7 @@ jobs: echo 'PROJECT_ID='$(jq -r '.data.organization.projectV2.id' project_data.json) >> $GITHUB_ENV - name: add issue to e2e project env: - GITHUB_TOKEN: ${{ secrets.ADD_TO_PROJECT_TOKEN }} + GITHUB_TOKEN: ${{ secrets.ADD_TO_TRIAGE_BOARD_TOKEN }} ISSUE_ID: ${{ github.event.issue.node_id }} run: | gh api graphql -f query=' diff --git a/.github/workflows/triage_closed_issue_comment.yml b/.github/workflows/triage_closed_issue_comment.yml index 82263c9f323..5c51eafd456 100644 --- a/.github/workflows/triage_closed_issue_comment.yml +++ b/.github/workflows/triage_closed_issue_comment.yml @@ -1,5 +1,10 @@ name: 'Triage: closed issue comment' on: + # makes this workflow reusable + workflow_call: + secrets: + ADD_TO_TRIAGE_BOARD_TOKEN: + required: true issue_comment: types: - created @@ -14,9 +19,9 @@ jobs: steps: - name: Get project data env: - GITHUB_TOKEN: ${{ secrets.ADD_TO_PROJECT_TOKEN }} + GITHUB_TOKEN: ${{ secrets.ADD_TO_TRIAGE_BOARD_TOKEN }} ORGANIZATION: 'cypress-io' - REPOSITORY: 'cypress' + REPOSITORY: ${{ github.event.repository.name }} PROJECT_NUMBER: 9 ISSUE_NUMBER: ${{ github.event.issue.number }} run: | @@ -68,7 +73,7 @@ jobs: echo 'NEW_ISSUE_OPTION_ID='$(jq -r '.data.organization.projectV2.field.options[] | select(.name== "New Issue") | .id' project_data.json) >> $GITHUB_ENV - name: Move issue to New Issue status env: - GITHUB_TOKEN: ${{ secrets.ADD_TO_PROJECT_TOKEN }} + GITHUB_TOKEN: ${{ secrets.ADD_TO_TRIAGE_BOARD_TOKEN }} if: env.STATUS == 'Closed' run: | gh api graphql -f query=' diff --git a/tooling/v8-snapshot/cache/linux/snapshot-meta.json b/tooling/v8-snapshot/cache/linux/snapshot-meta.json index 3d6bbe2b8bd..f3ab164e616 100644 --- a/tooling/v8-snapshot/cache/linux/snapshot-meta.json +++ b/tooling/v8-snapshot/cache/linux/snapshot-meta.json @@ -63,7 +63,6 @@ "./packages/network/node_modules/minimatch/minimatch.js", "./packages/proxy/lib/http/util/prerequests.ts", "./packages/server/lib/browsers/index.ts", - "./packages/server/lib/browsers/memory/index.ts", "./packages/server/lib/browsers/utils.ts", "./packages/server/lib/capture.js", "./packages/server/lib/cloud/exception.ts", @@ -996,6 +995,7 @@ "./packages/scaffold-config/index.js", "./packages/server/lib/browsers/chrome.ts", "./packages/server/lib/browsers/firefox.ts", + "./packages/server/lib/browsers/memory/index.ts", "./packages/server/lib/cache.js", "./packages/server/lib/cloud/api.ts", "./packages/server/lib/cloud/auth.ts", @@ -4676,6 +4676,16 @@ "./node_modules/yallist/yallist.js", "./node_modules/yn/index.js", "./node_modules/yn/lenient.js", + "./node_modules/zod/lib/ZodError.js", + "./node_modules/zod/lib/errors.js", + "./node_modules/zod/lib/external.js", + "./node_modules/zod/lib/helpers/errorUtil.js", + "./node_modules/zod/lib/helpers/parseUtil.js", + "./node_modules/zod/lib/helpers/typeAliases.js", + "./node_modules/zod/lib/helpers/util.js", + "./node_modules/zod/lib/index.js", + "./node_modules/zod/lib/locales/en.js", + "./node_modules/zod/lib/types.js", "./npm/webpack-batteries-included-preprocessor/empty.js", "./npm/webpack-preprocessor/dist/lib/typescript-overrides.js", "./package.json", @@ -5092,8 +5102,8 @@ "./packages/rewriter/node_modules/parse5/lib/utils/mixin.js", "./packages/root/index.js", "./packages/scaffold-config/src/commandFile.ts", - "./packages/scaffold-config/src/ct-detect-third-party.ts", "./packages/scaffold-config/src/component-index-template.ts", + "./packages/scaffold-config/src/ct-detect-third-party.ts", "./packages/scaffold-config/src/dependencies.ts", "./packages/scaffold-config/src/detect.ts", "./packages/scaffold-config/src/frameworks.ts", @@ -5389,5 +5399,5 @@ "./tooling/v8-snapshot/cache/linux/snapshot-entry.js" ], "deferredHashFile": "yarn.lock", - "deferredHash": "01abd62478db6a96641c734d3f71ca773474daf953a15922c4ee5a2cb1496fa9" + "deferredHash": "63057bdd5689459e149ffb67a1c057c2b829210d1db664db960a2cc6422c5908" } \ No newline at end of file From e6729a30a1c3f20f8fde8d322fd7b62327e03abf Mon Sep 17 00:00:00 2001 From: "cypress-bot[bot]" <+cypress-bot[bot]@users.noreply.github.com> Date: Wed, 22 Feb 2023 04:44:02 +0000 Subject: [PATCH 4/9] chore: updating v8 snapshot cache --- .../v8-snapshot/cache/win32/snapshot-meta.json | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/tooling/v8-snapshot/cache/win32/snapshot-meta.json b/tooling/v8-snapshot/cache/win32/snapshot-meta.json index 108ae189b2d..87840745fd6 100644 --- a/tooling/v8-snapshot/cache/win32/snapshot-meta.json +++ b/tooling/v8-snapshot/cache/win32/snapshot-meta.json @@ -63,7 +63,6 @@ "./packages/network/node_modules/minimatch/minimatch.js", "./packages/proxy/lib/http/util/prerequests.ts", "./packages/server/lib/browsers/index.ts", - "./packages/server/lib/browsers/memory/index.ts", "./packages/server/lib/browsers/utils.ts", "./packages/server/lib/capture.js", "./packages/server/lib/cloud/exception.ts", @@ -999,6 +998,7 @@ "./packages/scaffold-config/index.js", "./packages/server/lib/browsers/chrome.ts", "./packages/server/lib/browsers/firefox.ts", + "./packages/server/lib/browsers/memory/index.ts", "./packages/server/lib/cache.js", "./packages/server/lib/cloud/api.ts", "./packages/server/lib/cloud/auth.ts", @@ -4674,6 +4674,16 @@ "./node_modules/yallist/yallist.js", "./node_modules/yn/index.js", "./node_modules/yn/lenient.js", + "./node_modules/zod/lib/ZodError.js", + "./node_modules/zod/lib/errors.js", + "./node_modules/zod/lib/external.js", + "./node_modules/zod/lib/helpers/errorUtil.js", + "./node_modules/zod/lib/helpers/parseUtil.js", + "./node_modules/zod/lib/helpers/typeAliases.js", + "./node_modules/zod/lib/helpers/util.js", + "./node_modules/zod/lib/index.js", + "./node_modules/zod/lib/locales/en.js", + "./node_modules/zod/lib/types.js", "./npm/webpack-batteries-included-preprocessor/empty.js", "./npm/webpack-preprocessor/dist/lib/typescript-overrides.js", "./package.json", @@ -5090,8 +5100,8 @@ "./packages/rewriter/node_modules/parse5/lib/utils/mixin.js", "./packages/root/index.js", "./packages/scaffold-config/src/commandFile.ts", - "./packages/scaffold-config/src/ct-detect-third-party.ts", "./packages/scaffold-config/src/component-index-template.ts", + "./packages/scaffold-config/src/ct-detect-third-party.ts", "./packages/scaffold-config/src/dependencies.ts", "./packages/scaffold-config/src/detect.ts", "./packages/scaffold-config/src/frameworks.ts", @@ -5387,5 +5397,5 @@ "./tooling/v8-snapshot/cache/win32/snapshot-entry.js" ], "deferredHashFile": "yarn.lock", - "deferredHash": "b9ae1eca19566c39d1730431a6ca70d8c3a3218d1b0772fe7a3299249e3ccd46" + "deferredHash": "3e8ef6ff2c7b75e02c38175d187ed9d2ef7317facb9b9d0123d64a11a7551c7d" } \ No newline at end of file From e3d8f1afc7edd9d1704ae2eb591f894735ef7136 Mon Sep 17 00:00:00 2001 From: "cypress-bot[bot]" <+cypress-bot[bot]@users.noreply.github.com> Date: Wed, 22 Feb 2023 07:21:36 +0000 Subject: [PATCH 5/9] chore: updating v8 snapshot cache --- .circleci/workflows.yml | 4 +++- npm/vite-dev-server/client/initCypressTests.js | 4 +++- .../v8-snapshot/cache/darwin/snapshot-meta.json | 14 ++++++++++++-- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/.circleci/workflows.yml b/.circleci/workflows.yml index 0f0f0890104..778537e0bfc 100644 --- a/.circleci/workflows.yml +++ b/.circleci/workflows.yml @@ -30,6 +30,7 @@ mainBuildFilters: &mainBuildFilters - /^release\/\d+\.\d+\.\d+$/ # use the following branch as well to ensure that v8 snapshot cache updates are fully tested - 'update-v8-snapshot-cache-on-develop' + - 'lmiller/fixing-vite-windows' # usually we don't build Mac app - it takes a long time # but sometimes we want to really confirm we are doing the right thing @@ -68,6 +69,7 @@ windowsWorkflowFilters: &windows-workflow-filters or: - equal: [ develop, << pipeline.git.branch >> ] # use the following branch as well to ensure that v8 snapshot cache updates are fully tested + - equal: [ 'lmiller/fixing-vite-windows', << pipeline.git.branch >> ] - equal: [ 'update-v8-snapshot-cache-on-develop', << pipeline.git.branch >> ] - matches: pattern: /^release\/\d+\.\d+\.\d+$/ @@ -134,7 +136,7 @@ commands: - run: name: Check current branch to persist artifacts command: | - if [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "release/"* && "$CIRCLE_BRANCH" != "update-v8-snapshot-cache-on-develop" ]]; then + if [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "release/"* && "$CIRCLE_BRANCH" != "lmiller/fixing-vite-windows" ]]; then echo "Not uploading artifacts or posting install comment for this branch." circleci-agent step halt fi diff --git a/npm/vite-dev-server/client/initCypressTests.js b/npm/vite-dev-server/client/initCypressTests.js index 57b983ca8fd..f0602c119eb 100644 --- a/npm/vite-dev-server/client/initCypressTests.js +++ b/npm/vite-dev-server/client/initCypressTests.js @@ -34,7 +34,9 @@ if (supportFile) { // Using relative path wouldn't allow to load tests outside Vite project root folder // So we use the "@fs" bit to load the test file using its absolute path -const testFileAbsolutePathRoute = `${devServerPublicPathRoute}/@fs${CypressInstance.spec.absolute}` +// Normalize path to not include a leading slash (different on Win32 vs Unix) +const normalizedAbsolutePath = CypressInstance.spec.absolute.replace(/^\//, '') +const testFileAbsolutePathRoute = `${devServerPublicPathRoute}/@fs/${normalizedAbsolutePath}` /* Spec file import logic */ // We need a slash before /src/my-spec.js, this does not happen by default. diff --git a/tooling/v8-snapshot/cache/darwin/snapshot-meta.json b/tooling/v8-snapshot/cache/darwin/snapshot-meta.json index 3ef8368b0a7..1084eefe76a 100644 --- a/tooling/v8-snapshot/cache/darwin/snapshot-meta.json +++ b/tooling/v8-snapshot/cache/darwin/snapshot-meta.json @@ -4680,6 +4680,16 @@ "./node_modules/yallist/yallist.js", "./node_modules/yn/index.js", "./node_modules/yn/lenient.js", + "./node_modules/zod/lib/ZodError.js", + "./node_modules/zod/lib/errors.js", + "./node_modules/zod/lib/external.js", + "./node_modules/zod/lib/helpers/errorUtil.js", + "./node_modules/zod/lib/helpers/parseUtil.js", + "./node_modules/zod/lib/helpers/typeAliases.js", + "./node_modules/zod/lib/helpers/util.js", + "./node_modules/zod/lib/index.js", + "./node_modules/zod/lib/locales/en.js", + "./node_modules/zod/lib/types.js", "./npm/webpack-batteries-included-preprocessor/empty.js", "./npm/webpack-preprocessor/dist/lib/typescript-overrides.js", "./package.json", @@ -5096,8 +5106,8 @@ "./packages/rewriter/node_modules/parse5/lib/utils/mixin.js", "./packages/root/index.js", "./packages/scaffold-config/src/commandFile.ts", - "./packages/scaffold-config/src/ct-detect-third-party.ts", "./packages/scaffold-config/src/component-index-template.ts", + "./packages/scaffold-config/src/ct-detect-third-party.ts", "./packages/scaffold-config/src/dependencies.ts", "./packages/scaffold-config/src/detect.ts", "./packages/scaffold-config/src/frameworks.ts", @@ -5393,5 +5403,5 @@ "./tooling/v8-snapshot/cache/darwin/snapshot-entry.js" ], "deferredHashFile": "yarn.lock", - "deferredHash": "01abd62478db6a96641c734d3f71ca773474daf953a15922c4ee5a2cb1496fa9" + "deferredHash": "63057bdd5689459e149ffb67a1c057c2b829210d1db664db960a2cc6422c5908" } \ No newline at end of file From e712fb9e0397541ff4284e8903c37a0463729956 Mon Sep 17 00:00:00 2001 From: "cypress-bot[bot]" <+cypress-bot[bot]@users.noreply.github.com> Date: Thu, 23 Feb 2023 00:35:07 +0000 Subject: [PATCH 6/9] chore: updating v8 snapshot cache --- cli/CHANGELOG.md | 7 +- packages/server/lib/browsers/index.ts | 79 ++++++++++--- .../server/test/support/helpers/deferred.ts | 10 ++ .../test/unit/browsers/browsers_spec.js | 108 ++++++++++++++++++ .../unit/plugins/child/run_plugins_spec.js | 12 +- .../cache/linux/snapshot-meta.json | 2 +- 6 files changed, 190 insertions(+), 28 deletions(-) create mode 100644 packages/server/test/support/helpers/deferred.ts diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index c9a09bc1386..c7f3ad48bd2 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -1,7 +1,7 @@ ## 12.7.0 -_Released 03/1/2023 (PENDING)_ +_Released 02/28/2023 (PENDING)_ **Features:** @@ -14,9 +14,10 @@ _Released 03/1/2023 (PENDING)_ - Fixed an issue where cookies were being duplicated with the same hostname, but a prepended dot. Fixed an issue where cookies may not be expiring correctly. Fixes [#25174](https://github.com/cypress-io/cypress/issues/25174), [#25205](https://github.com/cypress-io/cypress/issues/25205) and [#25495](https://github.com/cypress-io/cypress/issues/25495). - Fixed an issue where cookies weren't being synced when the application was stable. Fixed in [#25855](https://github.com/cypress-io/cypress/pull/25855). Fixes [#25835](https://github.com/cypress-io/cypress/issues/25835). - Added missing TypeScript type definitions for the [`cy.reload()`](https://docs.cypress.io/api/commands/reload) command. Addressed in [#25779](https://github.com/cypress-io/cypress/pull/25779). -- Ensure Angular components are mounted inside the correct element. Fixes [#24385](https://github.com/cypress-io/cypress/issues/24385) -- Fix a bug where files outside the project root in a monorepo are not correctly served when using Vite. Addressed in [#25801](https://github.com/cypress-io/cypress/pull/25801) +- Ensure Angular components are mounted inside the correct element. Fixes [#24385](https://github.com/cypress-io/cypress/issues/24385). +- Fix a bug where files outside the project root in a monorepo are not correctly served when using Vite. Addressed in [#25801](https://github.com/cypress-io/cypress/pull/25801). - Fixed an issue where using [`cy.intercept`](https://docs.cypress.io/api/commands/intercept)'s `req.continue()` with a non-function parameter would not provide an appropriate error message. Fixed in [#25884](https://github.com/cypress-io/cypress/pull/25884). +- Fixed an issue where Cypress would erroneously launch and connect to multiple browser instances. Fixes [#24377](https://github.com/cypress-io/cypress/issues/24377). **Misc:** diff --git a/packages/server/lib/browsers/index.ts b/packages/server/lib/browsers/index.ts index 31e5b6e3c2e..c17d24970d4 100644 --- a/packages/server/lib/browsers/index.ts +++ b/packages/server/lib/browsers/index.ts @@ -15,23 +15,39 @@ const debug = Debug('cypress:server:browsers') const isBrowserFamily = check.oneOf(BROWSER_FAMILY) let instance: BrowserInstance | null = null +let launchAttempt = 0 -const kill = function (unbind = true, isProcessExit = false) { - // Clean up the instance when the browser is closed - if (!instance) { +interface KillOptions { + instance?: BrowserInstance + isProcessExit?: boolean + nullOut?: boolean + unbind?: boolean +} + +const kill = (options: KillOptions = {}) => { + options = _.defaults({}, options, { + instance, + isProcessExit: false, + unbind: true, + nullOut: true, + }) + + const instanceToKill = options.instance + + if (!instanceToKill) { debug('browsers.kill called with no active instance') return Promise.resolve() } - const _instance = instance - - instance = null + if (options.nullOut) { + instance = null + } return new Promise((resolve) => { - _instance.once('exit', () => { - if (unbind) { - _instance.removeAllListeners() + instanceToKill.once('exit', () => { + if (options.unbind) { + instanceToKill.removeAllListeners() } debug('browser process killed') @@ -41,9 +57,9 @@ const kill = function (unbind = true, isProcessExit = false) { debug('killing browser process') - _instance.isProcessExit = isProcessExit + instanceToKill.isProcessExit = options.isProcessExit - _instance.kill() + instanceToKill.kill() }) } @@ -86,7 +102,7 @@ async function getBrowserLauncher (browser: Browser, browsers: FoundBrowser[]): return utils.throwBrowserNotFound(browser.name, browsers) } -process.once('exit', () => kill(true, true)) +process.once('exit', () => kill({ isProcessExit: true })) export = { ensureAndGetByNameOrPath: utils.ensureAndGetByNameOrPath, @@ -136,7 +152,16 @@ export = { }, async open (browser: Browser, options: BrowserLaunchOpts, automation: Automation, ctx): Promise { - await kill(true) + // this global helps keep track of which launch attempt is the latest one + launchAttempt++ + + // capture the launch attempt number for this attempt, so that if the global + // one changes in the course of launching, we know another attempt has been + // made that should supercede it. see the long comment below for more details + const thisLaunchAttempt = launchAttempt + + // kill any currently open browser instance before launching a new one + await kill() _.defaults(options, { onBrowserOpen () {}, @@ -155,6 +180,34 @@ export = { debug('browser opened') + // in most cases, we'll kill any running browser instance before launching + // a new one when we call `await kill()` early in this function. + // however, the code that calls this sets a timeout and, if that timeout + // hits, it catches the timeout error and retries launching the browser by + // calling this function again. that means any attempt to launch the browser + // isn't necessarily canceled; we just ignore its success. it's possible an + // original attempt to launch the browser eventually does succeed after + // we've already called this function again on retry. if the 1st + // (now timed-out) browser launch succeeds after this attempt to kill it, + // the 1st instance gets created but then orphaned when we override the + // `instance` singleton after the 2nd attempt succeeds. subsequent code + // expects only 1 browser to be connected at a time, so this causes wonky + // things to occur because we end up connected to and receiving messages + // from 2 browser instances. + // + // to counteract this potential race condition, we use the `launchAttempt` + // global to essentially track which browser launch attempt is the latest + // one. the latest one should always be the correct one we want to connect + // to, so if the `launchAttempt` global has changed in the course of launching + // this browser, it means it has been orphaned and should be terminated. + // + // https://github.com/cypress-io/cypress/issues/24377 + if (thisLaunchAttempt !== launchAttempt) { + await kill({ instance: _instance, nullOut: false }) + + return null + } + instance = _instance instance.browser = browser diff --git a/packages/server/test/support/helpers/deferred.ts b/packages/server/test/support/helpers/deferred.ts new file mode 100644 index 00000000000..cef58fcdd99 --- /dev/null +++ b/packages/server/test/support/helpers/deferred.ts @@ -0,0 +1,10 @@ +export const deferred = () => { + let reject + let resolve + const promise = new Promise((_resolve, _reject) => { + resolve = _resolve + reject = _reject + }) + + return { promise, resolve, reject } +} diff --git a/packages/server/test/unit/browsers/browsers_spec.js b/packages/server/test/unit/browsers/browsers_spec.js index d8ff751aade..e5929a4e5eb 100644 --- a/packages/server/test/unit/browsers/browsers_spec.js +++ b/packages/server/test/unit/browsers/browsers_spec.js @@ -12,7 +12,9 @@ const { exec } = require('child_process') const util = require('util') const { createTestDataContext } = require('@packages/data-context/test/unit/helper') const electron = require('../../../lib/browsers/electron') +const chrome = require('../../../lib/browsers/chrome') const Promise = require('bluebird') +const { deferred } = require('../../support/helpers/deferred') const normalizeSnapshot = (str) => { return snapshot(stripAnsi(str)) @@ -156,6 +158,112 @@ describe('lib/browsers/index', () => { expect(err).to.have.property('message').to.contain(`Browser: ${chalk.yellow('foo-bad-bang')} was not found on your system`) }) }) + + // https://github.com/cypress-io/cypress/issues/24377 + it('terminates orphaned browser if it connects while launching another instance', async () => { + const browserOptions = [{ + family: 'chromium', + }, { + url: 'http://example.com', + onBrowserOpen () {}, + }, null, ctx] + + const launchBrowser1 = deferred() + const browserInstance1 = new EventEmitter() + + browserInstance1.kill = sinon.stub() + sinon.stub(chrome, 'open').onCall(0).returns(launchBrowser1.promise) + + // attempt to launch browser + const openBrowser1 = browsers.open(...browserOptions) + const launchBrowser2 = deferred() + const browserInstance2 = new EventEmitter() + + browserInstance2.kill = sinon.stub() + chrome.open.onCall(1).returns(launchBrowser2.promise) + + // original browser launch times out, so we retry launching the browser + const openBrowser2 = browsers.open(...browserOptions) + + // in the meantime, the 1st browser launches + launchBrowser1.resolve(browserInstance1) + // allow time for 1st browser to set instance before allowing 2nd + // browser launch to move forward + await Promise.delay(10) + // the 2nd browser launches + launchBrowser2.resolve(browserInstance2) + // if we exit too soon, it will clear the instance in `open`'s exit + // handler and not trigger the condition we're looking for + await Promise.delay(10) + // finishes killing the 1st browser + browserInstance1.emit('exit') + + await openBrowser1 + await openBrowser2 + + const currentInstance = browsers.getBrowserInstance() + + // clear out instance or afterEach hook will try to kill it and + // it won't resolve. make sure this is before the assertions or + // a failing one will prevent it from happening + browsers._setInstance(null) + + expect(browserInstance1.kill).to.be.calledOnce + expect(currentInstance).to.equal(browserInstance2) + }) + + // https://github.com/cypress-io/cypress/issues/24377 + it('terminates orphaned browser if it connects after another instance launches', async () => { + const browserOptions = [{ + family: 'chromium', + }, { + url: 'http://example.com', + onBrowserOpen () {}, + }, null, ctx] + + const launchBrowser1 = deferred() + const browserInstance1 = new EventEmitter() + + browserInstance1.kill = sinon.stub() + sinon.stub(chrome, 'open').onCall(0).returns(launchBrowser1.promise) + + // attempt to launch browser + const openBrowser1 = browsers.open(...browserOptions) + const launchBrowser2 = deferred() + const browserInstance2 = new EventEmitter() + + browserInstance2.kill = sinon.stub() + chrome.open.onCall(1).returns(launchBrowser2.promise) + + // original browser launch times out, so we retry launching the browser + const openBrowser2 = browsers.open(...browserOptions) + + // the 2nd browser launches + launchBrowser2.resolve(browserInstance2) + + await openBrowser2 + + // but then the 1st browser launches + launchBrowser1.resolve(browserInstance1) + + // wait a tick for exit listener to be set up, then send 'exit' + await Promise.delay(10) + // it should be killed (asserted below) + // this finishes killing the 1st browser + browserInstance1.emit('exit') + + await openBrowser1 + + const currentInstance = browsers.getBrowserInstance() + + // clear out instance or afterEach hook will try to kill it and + // it won't resolve. make sure this is before the assertions or + // a failing one will prevent it from happening + browsers._setInstance(null) + + expect(browserInstance1.kill).to.be.calledOnce + expect(currentInstance).to.equal(browserInstance2) + }) }) context('.extendLaunchOptionsFromPlugins', () => { diff --git a/packages/server/test/unit/plugins/child/run_plugins_spec.js b/packages/server/test/unit/plugins/child/run_plugins_spec.js index 9d6eebd0207..285a9761bde 100644 --- a/packages/server/test/unit/plugins/child/run_plugins_spec.js +++ b/packages/server/test/unit/plugins/child/run_plugins_spec.js @@ -10,21 +10,11 @@ const resolve = require(`../../../../lib/util/resolve`) const browserUtils = require(`../../../../lib/browsers/utils`) const Fixtures = require('@tooling/system-tests') const { RunPlugins } = require(`../../../../lib/plugins/child/run_plugins`) +const { deferred } = require('../../../support/helpers/deferred') const colorCodeRe = /\[[0-9;]+m/gm const pathRe = /\/?([a-z0-9_-]+\/)*[a-z0-9_-]+\/([a-z_]+\.\w+)[:0-9]+/gmi -const deferred = () => { - let reject - let resolve - const promise = new Promise((_resolve, _reject) => { - resolve = _resolve - reject = _reject - }) - - return { promise, resolve, reject } -} - const withoutColorCodes = (str) => { return str.replace(colorCodeRe, '') } diff --git a/tooling/v8-snapshot/cache/linux/snapshot-meta.json b/tooling/v8-snapshot/cache/linux/snapshot-meta.json index f3ab164e616..d15450fa408 100644 --- a/tooling/v8-snapshot/cache/linux/snapshot-meta.json +++ b/tooling/v8-snapshot/cache/linux/snapshot-meta.json @@ -5399,5 +5399,5 @@ "./tooling/v8-snapshot/cache/linux/snapshot-entry.js" ], "deferredHashFile": "yarn.lock", - "deferredHash": "63057bdd5689459e149ffb67a1c057c2b829210d1db664db960a2cc6422c5908" + "deferredHash": "0b865dfc2f62f16519ff310a66a64a34dd21f77af937b356903b683e43d4206b" } \ No newline at end of file From 8f448792f516e715c6585c7d3f746d95561296e5 Mon Sep 17 00:00:00 2001 From: "cypress-bot[bot]" <+cypress-bot[bot]@users.noreply.github.com> Date: Thu, 23 Feb 2023 01:07:38 +0000 Subject: [PATCH 7/9] chore: updating v8 snapshot cache --- tooling/v8-snapshot/cache/win32/snapshot-meta.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tooling/v8-snapshot/cache/win32/snapshot-meta.json b/tooling/v8-snapshot/cache/win32/snapshot-meta.json index 87840745fd6..f811dbb28b4 100644 --- a/tooling/v8-snapshot/cache/win32/snapshot-meta.json +++ b/tooling/v8-snapshot/cache/win32/snapshot-meta.json @@ -5397,5 +5397,5 @@ "./tooling/v8-snapshot/cache/win32/snapshot-entry.js" ], "deferredHashFile": "yarn.lock", - "deferredHash": "3e8ef6ff2c7b75e02c38175d187ed9d2ef7317facb9b9d0123d64a11a7551c7d" + "deferredHash": "d9f8eb235f769d2ad0c226988fd9114d55e3bdbd42e78ba0804d8fa8e6f1f4b7" } \ No newline at end of file From 8f2d793606ad007da2a54a124c1cdf0cb871a6c2 Mon Sep 17 00:00:00 2001 From: "cypress-bot[bot]" <+cypress-bot[bot]@users.noreply.github.com> Date: Thu, 23 Feb 2023 01:44:30 +0000 Subject: [PATCH 8/9] chore: updating v8 snapshot cache --- tooling/v8-snapshot/cache/darwin/snapshot-meta.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tooling/v8-snapshot/cache/darwin/snapshot-meta.json b/tooling/v8-snapshot/cache/darwin/snapshot-meta.json index 1084eefe76a..eeb60c74db4 100644 --- a/tooling/v8-snapshot/cache/darwin/snapshot-meta.json +++ b/tooling/v8-snapshot/cache/darwin/snapshot-meta.json @@ -5403,5 +5403,5 @@ "./tooling/v8-snapshot/cache/darwin/snapshot-entry.js" ], "deferredHashFile": "yarn.lock", - "deferredHash": "63057bdd5689459e149ffb67a1c057c2b829210d1db664db960a2cc6422c5908" + "deferredHash": "0b865dfc2f62f16519ff310a66a64a34dd21f77af937b356903b683e43d4206b" } \ No newline at end of file From 310b7e02afa13669fd5bccf3091acf54c2015bb6 Mon Sep 17 00:00:00 2001 From: "cypress-bot[bot]" <+cypress-bot[bot]@users.noreply.github.com> Date: Fri, 24 Feb 2023 00:34:01 +0000 Subject: [PATCH 9/9] chore: updating v8 snapshot cache --- packages/app/src/debug/DebugSpec.cy.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/app/src/debug/DebugSpec.cy.tsx b/packages/app/src/debug/DebugSpec.cy.tsx index b22c893ea14..c30f21ab575 100644 --- a/packages/app/src/debug/DebugSpec.cy.tsx +++ b/packages/app/src/debug/DebugSpec.cy.tsx @@ -485,8 +485,6 @@ describe('Run Failures button', () => { cy.findByTestId('run-failures').realHover() cy.findByTestId('run-all-failures-tooltip').should('be.visible').contains('Spec was not found locally') - - cy.percySnapshot() }) it('is disabled if run testing-type differs from the current testing-type', () => { @@ -563,7 +561,6 @@ describe('Open in IDE', () => { cy.findByLabelText(defaultMessages.debugPage.openFile.openInIDE).as('openInIDE').realHover() cy.findByTestId('open-in-ide-tooltip').should('be.visible').and('contain', defaultMessages.debugPage.openFile.openInIDE) - cy.percySnapshot() cy.get('@openInIDE').click() @@ -576,6 +573,5 @@ describe('Open in IDE', () => { cy.findByLabelText(defaultMessages.debugPage.openFile.notFoundLocally).as('openInIDE').realHover() cy.findByTestId('open-in-ide-disabled-tooltip').should('be.visible').and('contain', defaultMessages.debugPage.openFile.notFoundLocally) - cy.percySnapshot() }) })