Skip to content

Commit ba6b391

Browse files
Merge branch 'develop' into feat/cy-prompt
2 parents 2e4c8e4 + a20aa3b commit ba6b391

File tree

21 files changed

+638
-98
lines changed

21 files changed

+638
-98
lines changed

.circleci/workflows.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
version: 2.1
22

3-
chrome-stable-version: &chrome-stable-version "137.0.7151.103"
4-
chrome-beta-version: &chrome-beta-version "138.0.7204.23"
3+
chrome-stable-version: &chrome-stable-version "138.0.7204.49"
4+
chrome-beta-version: &chrome-beta-version "139.0.7258.5"
55
firefox-stable-version: &firefox-stable-version "137.0"
66

77
orbs:

cli/CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
<!-- See the ../guides/writing-the-cypress-changelog.md for details on writing the changelog. -->
2+
## 14.5.1
3+
4+
_Released 7/01/2025 (PENDING)_
5+
6+
**Dependency Updates:**
7+
8+
- Updated `pbkdf2` from `3.1.2` to `3.1.3`. This removes the [SNYK-JS-PBKDF2-10495498](https://security.snyk.io/vuln/SNYK-JS-PBKDF2-10495498) vulnerability being reported in security scans. Addressed in [#31941](https://github.com/cypress-io/cypress/pull/31941).
9+
210
## 14.5.0
311

412
_Released 6/17/2025_
@@ -10,6 +18,7 @@ _Released 6/17/2025_
1018
**Bugfixes:**
1119

1220
- Fixed an issue when using `Cypress.stop()` where a run may be aborted prior to receiving the required runner events causing Test Replay to not be available. Addresses [#31781](https://github.com/cypress-io/cypress/issues/31781).
21+
- Fixed an issue where prerequests with Firefox BiDi were prematurely being removed or matched incorrectly. Addresses [#31482](https://github.com/cypress-io/cypress/issues/31482).
1322

1423
## 14.4.1
1524

npm/webpack-batteries-included-preprocessor/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"coffee-loader": "^4.0.0",
2424
"coffeescript": "2.6.0",
2525
"constants-browserify": "^1.0.0",
26-
"crypto-browserify": "^3.12.0",
26+
"crypto-browserify": "^3.12.1",
2727
"debug": "^4.3.4",
2828
"domain-browser": "^4.22.0",
2929
"events": "^3.3.0",

packages/driver/cypress/e2e/cy/snapshot.cy.js

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,6 @@ describe('driver/src/cy/snapshots', () => {
55
beforeEach(() => {
66
cy.visit('/fixtures/invalid_html.html')
77
})
8-
9-
it('can snapshot html with invalid attributes', () => {
10-
const { htmlAttrs } = cy.createSnapshot()
11-
12-
expect(htmlAttrs).to.eql({
13-
foo: 'bar',
14-
})
15-
})
168
})
179

1810
context('snapshot no html/doc', () => {

packages/network/lib/agent.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ export const createProxySock = (opts: CreateProxySockOpts, cb: CreateProxySockCb
126126

127127
export const isRequestHttps = (options: http.RequestOptions) => {
128128
// WSS connections will not have an href, but you can tell protocol from the defaultAgent
129-
return _.get(options, '_defaultAgent.protocol') === 'https:' || (options.href || '').slice(0, 6) === 'https'
129+
return _.get(options, '_defaultAgent.protocol') === 'https:' || (options.href || '').slice(0, 6) === 'https:'
130130
}
131131

132132
export const isResponseStatusCode200 = (head: string) => {
@@ -210,6 +210,20 @@ export class CombinedAgent {
210210
}
211211
}
212212

213+
// If the path property is a fully qualified URL, which is what as Axios appears to set,
214+
// parse the URL and set the href, path, and port based on this path
215+
if (typeof options.path === 'string' && /^http(s)?:\/\//.test(options.path)) {
216+
const pathUrl = new URL(options.path)
217+
const portToSet = pathUrl.port ?? options.port
218+
219+
options.href = options.path
220+
options.path = pathUrl.pathname
221+
222+
if (portToSet) {
223+
options.port = Number(portToSet)
224+
}
225+
}
226+
213227
const isHttps = isRequestHttps(options)
214228

215229
if (!options.href) {
@@ -443,7 +457,3 @@ class HttpsAgent extends https.Agent {
443457
const agent = new CombinedAgent()
444458

445459
export default agent
446-
447-
export const httpsAgent = new HttpsAgent()
448-
449-
export const httpAgent = new HttpAgent()

packages/proxy/lib/http/util/prerequests.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ export class PreRequests {
141141
const now = Date.now()
142142

143143
this.pendingPreRequests.removeMatching(({ cdpRequestWillBeSentReceivedTimestamp, browserPreRequest }) => {
144-
if (cdpRequestWillBeSentReceivedTimestamp + this.sweepInterval < now) {
144+
if (cdpRequestWillBeSentReceivedTimestamp !== 0 && (cdpRequestWillBeSentReceivedTimestamp + this.sweepInterval < now)) {
145145
debugVerbose('timed out unmatched pre-request: %o', browserPreRequest)
146146
metrics.unmatchedPreRequests++
147147

packages/proxy/test/unit/http/util/prerequests.spec.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,4 +309,20 @@ describe('http/util/prerequests', () => {
309309
expect(preRequests.pendingPreRequests.length).to.eq(1)
310310
expect(preRequests.pendingPreRequests.shift('GET-foo|bar')).not.to.be.undefined
311311
})
312+
313+
it('does not remove pre-requests when sweeping if cdpRequestWillBeSentReceivedTimestamp is 0', async () => {
314+
// set the current time to 1000 ms
315+
sinon.stub(Date, 'now').returns(1000)
316+
317+
// set a sweeper timer of 10 ms
318+
preRequests = new PreRequests(10, 10)
319+
preRequests.setProtocolManager(protocolManager)
320+
321+
preRequests.addPending({ requestId: '1234', url: 'foo', method: 'GET', cdpRequestWillBeSentReceivedTimestamp: 0 } as BrowserPreRequest)
322+
323+
// give the sweeper plenty of time to run. Iur request should still not be removed
324+
await new Promise((resolve) => setTimeout(resolve, 1000))
325+
326+
expect(preRequests.pendingPreRequests.length).to.eq(1)
327+
})
312328
})

packages/server/lib/browsers/bidi_automation.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,10 +172,13 @@ export class BidiAutomation {
172172

173173
const resourceType = normalizeResourceType(params.request.initiatorType)
174174

175+
const urlWithoutHash = url.includes('#') ? url.substring(0, url.indexOf('#')) : url
176+
175177
const browserPreRequest: BrowserPreRequest = {
176178
requestId: params.request.request,
177179
method: params.request.method,
178-
url,
180+
// urls coming into the http middleware contain query params, but lack the hash. To get an accurate key to match on the prerequest, we need to remove the hash.
181+
url: urlWithoutHash,
179182
headers: parsedHeaders,
180183
resourceType,
181184
originalResourceType: params.request.initiatorType || params.request.destination,

packages/server/lib/cloud/api/cloud_request.ts

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,44 @@
33
*/
44
import os from 'os'
55

6+
import followRedirects from 'follow-redirects'
67
import axios, { AxiosInstance } from 'axios'
7-
88
import pkg from '@packages/root'
9-
import { httpAgent, httpsAgent } from '@packages/network/lib/agent'
9+
import agent from '@packages/network/lib/agent'
1010

1111
import app_config from '../../../config/app.json'
1212
import { installErrorTransform } from './axios_middleware/transform_error'
1313
import { installLogging } from './axios_middleware/logging'
1414

1515
// initialized with an export for testing purposes
16-
export const _create = (): AxiosInstance => {
16+
export const _create = (options: { baseURL?: string } = {}): AxiosInstance => {
1717
const cfgKey = process.env.CYPRESS_CONFIG_ENV || process.env.CYPRESS_INTERNAL_ENV || 'development'
1818

1919
const instance = axios.create({
20-
baseURL: app_config[cfgKey].api_url,
21-
httpAgent,
22-
httpsAgent,
20+
baseURL: options.baseURL ?? app_config[cfgKey].api_url,
21+
httpAgent: agent,
22+
httpsAgent: agent,
2323
headers: {
2424
'x-os-name': os.platform(),
2525
'x-cypress-version': pkg.version,
2626
'User-Agent': `cypress/${pkg.version}`,
2727
},
28+
transport: {
29+
// https://github.com/axios/axios/issues/6313#issue-2198831362
30+
// Tapping into the transport seems the only way to handle this at the moment:
31+
// https://github.com/axios/axios/blob/a406a93e2d99c3317596f02f3537f5457a2a80fd/lib/adapters/http.js#L438-L450
32+
request (options, cb) {
33+
if ((process.env.HTTP_PROXY || process.env.HTTPS_PROXY) && options.headers['Proxy-Authorization']) {
34+
delete options.headers['Proxy-Authorization']
35+
}
36+
37+
if (/https:?/.test(options.protocol)) {
38+
return followRedirects.https.request(options, cb)
39+
}
40+
41+
return followRedirects.http.request(options, cb)
42+
},
43+
},
2844
})
2945

3046
installLogging(instance)

packages/server/lib/cloud/api/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const errors = require('../../errors')
1515
import Bluebird from 'bluebird'
1616

1717
import type { AfterSpecDurations } from '@packages/types'
18-
import { agent } from '@packages/network'
18+
import agent from '@packages/network/lib/agent'
1919
import type { CombinedAgent } from '@packages/network/lib/agent'
2020

2121
import { apiUrl, apiRoutes, makeRoutes } from '../routes'
@@ -479,7 +479,7 @@ export default {
479479
.catch(tagError)
480480
},
481481

482-
createInstance (runId: string, body: CreateInstanceRequestBody, timeout: number = 0): Bluebird<CreateInstanceResponse> {
482+
createInstance (runId: string, body: CreateInstanceRequestBody, timeout?: number): Bluebird<CreateInstanceResponse> {
483483
return retryWithBackoff((attemptIndex) => {
484484
return rp.post({
485485
body,

0 commit comments

Comments
 (0)