Skip to content

Commit 25f0fd0

Browse files
AtofStrykergithub-actions[bot]cypress-bot[bot]
authored
breaking: remove CDP from firefox with Cypress 15 (#31200)
* chore: updating v8 snapshot cache (#31422) Co-authored-by: cypress-bot[bot] <+cypress-bot[bot]@users.noreply.github.com> * breaking: remove CDP from firefox with Cypress 15 [run ci] * chore: code review updates --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: cypress-bot[bot] <+cypress-bot[bot]@users.noreply.github.com>
1 parent 534324f commit 25f0fd0

File tree

17 files changed

+136
-727
lines changed

17 files changed

+136
-727
lines changed

.circleci/workflows.yml

-31
Original file line numberDiff line numberDiff line change
@@ -656,11 +656,6 @@ commands:
656656
description: run subset of tests with injectDocumentDomain config enabled
657657
type: boolean
658658
default: false
659-
is-firefox-cdp:
660-
description: whether or not the group should be associated to the firefox CDP
661-
run or not. This is determined by the browser version.
662-
type: boolean
663-
default: false
664659

665660
steps:
666661
- restore_cached_workspace
@@ -701,9 +696,6 @@ commands:
701696
if << parameters.inject-document-domain >> ; then
702697
YARN_CMD="cypress:run:inject-document-domain"
703698
PARALLEL="--parallel --group 5x-driver-inject-document-domain-<<parameters.browser>>"
704-
elif << parameters.is-firefox-cdp >> ; then
705-
YARN_CMD="cypress:run"
706-
PARALLEL="--parallel --group 5x-driver-cdp-<<parameters.browser>>"
707699
else
708700
YARN_CMD="cypress:run"
709701
PARALLEL="--parallel --group 5x-driver-<<parameters.browser>>"
@@ -2136,18 +2128,6 @@ jobs:
21362128
- run-driver-integration-tests:
21372129
browser: firefox
21382130

2139-
# Runs the driver tests using firefox 134, which does NOT use WebDriver BiDi
2140-
# This is to test and make sure there aren't regressions with the old CDP driver
2141-
driver-integration-tests-firefox-cdp:
2142-
<<: *defaults
2143-
resource_class: medium+
2144-
parallelism: 5
2145-
steps:
2146-
- run-driver-integration-tests:
2147-
browser: firefox
2148-
firefox-version: "134.0.2"
2149-
is-firefox-cdp: true
2150-
21512131
driver-integration-tests-electron:
21522132
<<: *defaults
21532133
parallelism: 5
@@ -2888,7 +2868,6 @@ linux-x64-workflow: &linux-x64-workflow
28882868
- run-webpack-dev-server-integration-tests
28892869
- run-vite-dev-server-integration-tests
28902870
- driver-integration-tests-firefox
2891-
- driver-integration-tests-firefox-cdp
28922871
- driver-integration-tests-chrome
28932872
- driver-integration-tests-chrome-inject-document-domain
28942873
- driver-integration-tests-chrome-beta-inject-document-domain
@@ -2964,10 +2943,6 @@ linux-x64-workflow: &linux-x64-workflow
29642943
context: test-runner:cypress-record-key
29652944
requires:
29662945
- build
2967-
- driver-integration-tests-firefox-cdp:
2968-
context: test-runner:cypress-record-key
2969-
requires:
2970-
- build
29712946
- driver-integration-tests-electron:
29722947
context: test-runner:cypress-record-key
29732948
requires:
@@ -3110,7 +3085,6 @@ linux-x64-workflow: &linux-x64-workflow
31103085
- linux-lint
31113086
- percy-finalize
31123087
- driver-integration-tests-firefox
3113-
- driver-integration-tests-firefox-cdp
31143088
- driver-integration-tests-chrome
31153089
- driver-integration-tests-chrome-beta
31163090
- driver-integration-tests-chrome-inject-document-domain
@@ -3366,10 +3340,6 @@ linux-x64-contributor-workflow: &linux-x64-contributor-workflow
33663340
context: test-runner:cypress-record-key
33673341
requires:
33683342
- contributor-pr
3369-
- driver-integration-tests-firefox-cdp:
3370-
context: test-runner:cypress-record-key
3371-
requires:
3372-
- contributor-pr
33733343
- driver-integration-tests-electron:
33743344
context: test-runner:cypress-record-key
33753345
requires:
@@ -3511,7 +3481,6 @@ linux-x64-contributor-workflow: &linux-x64-contributor-workflow
35113481
- linux-lint
35123482
- percy-finalize
35133483
- driver-integration-tests-firefox
3514-
- driver-integration-tests-firefox-cdp
35153484
- driver-integration-tests-chrome
35163485
- driver-integration-tests-chrome-beta
35173486
- driver-integration-tests-electron

cli/CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
<!-- See the ../guides/writing-the-cypress-changelog.md for details on writing the changelog. -->
22
## 15.0.0
33

4-
_Released 7/1/2025 (PENDING)_
4+
_Released 07/01/2025 (PENDING)_
55

66
**Breaking Changes:**
77

88
- Removed support for Node.js 18 and Node.js 23. Addresses [#31302](https://github.com/cypress-io/cypress/issues/31302).
9+
- Removed support for [Chrome DevTools Protocol](https://chromedevtools.github.io/devtools-protocol) with the [firefox](https://www.mozilla.org/) browser. Addresses [#31189](https://github.com/cypress-io/cypress/issues/31189).
910

1011
## 14.2.2
1112

packages/errors/src/errors.ts

-3
Original file line numberDiff line numberDiff line change
@@ -1193,9 +1193,6 @@ export const AllCypressErrors = {
11931193
CDP_RETRYING_CONNECTION: (attempt: string | number, browserName: string, connectRetryThreshold: number) => {
11941194
return errTemplate`Still waiting to connect to ${fmt.off(_.capitalize(browserName))}, retrying in 1 second ${fmt.meta(`(attempt ${attempt}/${connectRetryThreshold})`)}`
11951195
},
1196-
CDP_FIREFOX_DEPRECATED: () => {
1197-
return errTemplate`Since Firefox 129, Chrome DevTools Protocol (CDP) has been deprecated in Firefox. In Firefox 135 and above, Cypress defaults to automating the Firefox browser with WebDriver BiDi. Cypress will no longer support CDP within Firefox in the future and is planned for removal in Cypress 15.`
1198-
},
11991196
BROWSER_PROCESS_CLOSED_UNEXPECTEDLY: (browserName: string) => {
12001197
return errTemplate`\
12011198
We detected that the ${fmt.highlight(browserName)} browser process closed unexpectedly.

packages/errors/test/unit/visualSnapshotErrors_spec.ts

-5
Original file line numberDiff line numberDiff line change
@@ -1112,11 +1112,6 @@ describe('visual error templates', () => {
11121112
default: [1, 'chrome', 62],
11131113
}
11141114
},
1115-
CDP_FIREFOX_DEPRECATED: () => {
1116-
return {
1117-
default: [],
1118-
}
1119-
},
11201115
BROWSER_PROCESS_CLOSED_UNEXPECTEDLY: () => {
11211116
return {
11221117
default: ['chrome'],

packages/extension/app/v2/background.js

-48
Original file line numberDiff line numberDiff line change
@@ -31,23 +31,6 @@ const checkIfFirefox = async () => {
3131
return name === 'Firefox'
3232
}
3333

34-
// this check only applies to firefox versioning!
35-
const isBiDiEnabled = async (config) => {
36-
if (!browser || !get(browser, 'runtime.getBrowserInfo') || config.IS_CDP_FORCED_FOR_FIREFOX) {
37-
return false
38-
}
39-
40-
const { version } = await browser.runtime.getBrowserInfo()
41-
42-
if (version) {
43-
const [majorVersion] = version.split('.').map(Number)
44-
45-
return majorVersion >= 135
46-
}
47-
48-
return false
49-
}
50-
5134
const connect = function (host, path, extraOpts) {
5235
const listenToCookieChanges = once(() => {
5336
return browser.cookies.onChanged.addListener((info) => {
@@ -84,30 +67,6 @@ const connect = function (host, path, extraOpts) {
8467
})
8568
})
8669

87-
const listenToOnBeforeHeaders = once(() => {
88-
// adds a header to the request to mark it as a request for the AUT frame
89-
// itself, so the proxy can utilize that for injection purposes
90-
browser.webRequest.onBeforeSendHeaders.addListener((details) => {
91-
if (
92-
// parentFrameId: 0 means the parent is the top-level, so if it isn't
93-
// 0, it's nested inside the AUT and can't be the AUT itself
94-
details.parentFrameId !== 0
95-
// is the spec frame, not the AUT
96-
|| details.url.includes('__cypress')
97-
) return
98-
99-
return {
100-
requestHeaders: [
101-
...details.requestHeaders,
102-
{
103-
name: 'X-Cypress-Is-AUT-Frame',
104-
value: 'true',
105-
},
106-
],
107-
}
108-
}, { urls: ['<all_urls>'], types: ['sub_frame'] }, ['blocking', 'requestHeaders'])
109-
})
110-
11170
const fail = (id, err) => {
11271
return ws.emit('automation:response', id, {
11372
__error: err.message,
@@ -167,13 +126,6 @@ const connect = function (host, path, extraOpts) {
167126
if (isFirefox) {
168127
// Non-Firefox browsers use CDP for this instead
169128
listenToDownloads()
170-
// if BiDi is enabled, BiDi will handle the network interception.
171-
// Otherwise, CDP does not support it for Firefox and we need to listen for it here.
172-
const isBiDiTurnedOn = await isBiDiEnabled(config)
173-
174-
if (!isBiDiTurnedOn) {
175-
listenToOnBeforeHeaders()
176-
}
177129
}
178130
})
179131

packages/extension/test/integration/v2/background_spec.js

-114
Original file line numberDiff line numberDiff line change
@@ -293,120 +293,6 @@ describe('app/background', () => {
293293
})
294294
})
295295

296-
context('add header to aut iframe requests', () => {
297-
beforeEach(() => {
298-
browser.runtime.getBrowserInfo = sinon.stub().resolves({ name: 'Firefox', version: '135.0.1' })
299-
})
300-
301-
it('allows for CDP to be used as an escape hatch if BiDi would otherwise be enabled', async function () {
302-
sinon.stub(browser.webRequest.onBeforeSendHeaders, 'addListener')
303-
304-
await this.connect({
305-
IS_CDP_FORCED_FOR_FIREFOX: true,
306-
})
307-
308-
expect(browser.webRequest.onBeforeSendHeaders.addListener).to.be.called
309-
})
310-
311-
context('BiDi enabled', () => {
312-
it('does not attach onBeforeSendHeaders listener if BiDi is enabled', async function () {
313-
sinon.stub(browser.webRequest.onBeforeSendHeaders, 'addListener')
314-
315-
await this.connect()
316-
317-
expect(browser.webRequest.onBeforeSendHeaders.addListener).not.to.be.called
318-
})
319-
})
320-
321-
context('CDP enabled', () => {
322-
beforeEach(() => {
323-
browser.runtime.getBrowserInfo = sinon.stub().resolves({ name: 'Firefox', version: '134' })
324-
})
325-
326-
it('does not add header if it is the top frame', async function () {
327-
const details = {
328-
parentFrameId: -1,
329-
}
330-
331-
sinon.stub(browser.webRequest.onBeforeSendHeaders, 'addListener')
332-
333-
await this.connect()
334-
335-
const result = browser.webRequest.onBeforeSendHeaders.addListener.lastCall.args[0](details)
336-
337-
expect(result).to.be.undefined
338-
})
339-
340-
it('does not add header if it is a nested frame', async function () {
341-
const details = {
342-
parentFrameId: 12345,
343-
}
344-
345-
sinon.stub(browser.webRequest.onBeforeSendHeaders, 'addListener')
346-
347-
await this.connect()
348-
349-
const result = browser.webRequest.onBeforeSendHeaders.addListener.lastCall.args[0](details)
350-
351-
expect(result).to.be.undefined
352-
})
353-
354-
it('does not add header if it is a spec frame request', async function () {
355-
const details = {
356-
parentFrameId: 0,
357-
type: 'sub_frame',
358-
url: '/__cypress/integration/spec.js',
359-
}
360-
361-
sinon.stub(browser.webRequest.onBeforeSendHeaders, 'addListener')
362-
363-
await this.connect()
364-
const result = browser.webRequest.onBeforeSendHeaders.addListener.lastCall.args[0](details)
365-
366-
expect(result).to.be.undefined
367-
})
368-
369-
it('appends X-Cypress-Is-AUT-Frame header to AUT iframe request', async function () {
370-
const details = {
371-
parentFrameId: 0,
372-
type: 'sub_frame',
373-
url: 'http://localhost:3000/index.html',
374-
requestHeaders: [
375-
{ name: 'X-Foo', value: 'Bar' },
376-
],
377-
}
378-
379-
sinon.stub(browser.webRequest.onBeforeSendHeaders, 'addListener')
380-
381-
await this.connect()
382-
const result = browser.webRequest.onBeforeSendHeaders.addListener.lastCall.args[0](details)
383-
384-
expect(result).to.deep.equal({
385-
requestHeaders: [
386-
{
387-
name: 'X-Foo',
388-
value: 'Bar',
389-
},
390-
{
391-
name: 'X-Cypress-Is-AUT-Frame',
392-
value: 'true',
393-
},
394-
],
395-
})
396-
})
397-
398-
it('does not add before-headers listener if in non-Firefox browser', async function () {
399-
browser.runtime.getBrowserInfo = undefined
400-
401-
const onBeforeSendHeaders = sinon.stub(browser.webRequest.onBeforeSendHeaders, 'addListener')
402-
403-
await this.connect()
404-
405-
expect(onBeforeSendHeaders).not.to.be.called
406-
})
407-
})
408-
})
409-
410296
context('.getAll', () => {
411297
it('resolves with specific cookie properties', () => {
412298
sinon.stub(browser.cookies, 'getAll').resolves([

packages/graphql/schemas/schema.graphql

-1
Original file line numberDiff line numberDiff line change
@@ -1129,7 +1129,6 @@ enum ErrorTypeEnum {
11291129
CANNOT_TRASH_ASSETS
11301130
CDP_COULD_NOT_CONNECT
11311131
CDP_COULD_NOT_RECONNECT
1132-
CDP_FIREFOX_DEPRECATED
11331132
CDP_RETRYING_CONNECTION
11341133
CDP_VERSION_TOO_OLD
11351134
CHROME_WEB_SECURITY_NOT_SUPPORTED

packages/launcher/lib/known-browsers.ts

+23-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,24 @@
11
import type { Browser, BrowserValidatorResult, FoundBrowser } from '@packages/types'
22

3+
const firefoxValidatorFn = (browser: FoundBrowser, platform: NodeJS.Platform): BrowserValidatorResult => {
4+
try {
5+
if (browser.majorVersion) {
6+
const majorVersion = Number(browser.majorVersion)
7+
8+
if (majorVersion < 135) {
9+
return {
10+
isSupported: false,
11+
warningMessage: `Cypress does not support running ${browser.displayName} version ${browser.majorVersion} due to lack of WebDriver BiDi support. To use ${browser.displayName} with Cypress, install version 135 or newer.`,
12+
}
13+
}
14+
}
15+
} catch (e) { /* empty */ }
16+
17+
return {
18+
isSupported: true,
19+
}
20+
}
21+
322
/** list of the browsers we can detect and use by default */
423
export const knownBrowsers: Browser[] = [
524
{
@@ -62,9 +81,10 @@ export const knownBrowsers: Browser[] = [
6281
family: 'firefox',
6382
channel: 'stable',
6483
displayName: 'Firefox',
65-
// Mozilla Firefox 70.0.1
84+
// Mozilla Firefox 135.0.1
6685
versionRegex: /^Mozilla Firefox ([^\sab]+)$/m,
6786
binary: 'firefox',
87+
validator: firefoxValidatorFn,
6888
},
6989
{
7090
name: 'firefox',
@@ -75,6 +95,7 @@ export const knownBrowsers: Browser[] = [
7595
versionRegex: /^Mozilla Firefox (\S+b\S*)$/m,
7696
// ubuntu PPAs install it as firefox
7797
binary: ['firefox-developer-edition', 'firefox'],
98+
validator: firefoxValidatorFn,
7899
},
79100
{
80101
name: 'firefox',
@@ -85,6 +106,7 @@ export const knownBrowsers: Browser[] = [
85106
versionRegex: /^Mozilla Firefox (\S+a\S*)$/m,
86107
// ubuntu PPAs install it as firefox-trunk
87108
binary: ['firefox-nightly', 'firefox-trunk'],
109+
validator: firefoxValidatorFn,
88110
},
89111
{
90112
name: 'edge',

packages/launcher/test/unit/browsers_spec.ts

+19
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,25 @@ describe('browsers', () => {
7171
expect(result.isSupported).to.be.true
7272
expect(result.warningMessage).to.be.undefined
7373
})
74+
75+
describe('firefox validation', () => {
76+
const FIREFOX_KNOWN_BROWSER_CHANNELS = knownBrowsers.filter((browser) => {
77+
return browser.family === 'firefox'
78+
})
79+
80+
FIREFOX_KNOWN_BROWSER_CHANNELS.forEach((browser) => {
81+
it(`${browser.channel}: fails validation when Firefox major version is below 135`, () => {
82+
// @ts-expect-error
83+
const result = browser.validator({
84+
majorVersion: '134',
85+
displayName: 'Firefox',
86+
})
87+
88+
expect(result.isSupported).to.be.false
89+
expect(result.warningMessage).to.equal('Cypress does not support running Firefox version 134 due to lack of WebDriver BiDi support. To use Firefox with Cypress, install version 135 or newer.')
90+
})
91+
})
92+
})
7493
})
7594
})
7695
})

0 commit comments

Comments
 (0)