Skip to content

Commit 15f7300

Browse files
fix: issue with service worker attachments (#28147)
Co-authored-by: Emily Rohrbough <[email protected]>
1 parent 09fa9d7 commit 15f7300

File tree

5 files changed

+63
-12
lines changed

5 files changed

+63
-12
lines changed

cli/CHANGELOG.md

+8
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+
## 13.3.4
3+
4+
_Released 11/7/2023 (PENDING)_
5+
6+
**Bugfixes:**
7+
8+
- Fixed a regression in [`13.3.2`](https://docs.cypress.io/guides/references/changelog/13.3.2) where loading a service worker and immediately reloading the page can cause a crash. Fixes [#28141](https://github.com/cypress-io/cypress/issues/28141).
9+
210
## 13.3.3
311

412
_Released 10/24/2023_

packages/server/lib/browsers/browser-cri-client.ts

+10-5
Original file line numberDiff line numberDiff line change
@@ -198,12 +198,17 @@ export class BrowserCriClient {
198198
// The basic approach here is we attach to targets and enable network traffic
199199
// We must attach in a paused state so that we can enable network traffic before the target starts running.
200200
browserClient.on('Target.attachedToTarget', async (event) => {
201-
if (event.targetInfo.type !== 'page') {
202-
await browserClient.send('Network.enable', protocolManager?.networkEnableOptions ?? DEFAULT_NETWORK_ENABLE_OPTIONS, event.sessionId)
203-
}
201+
try {
202+
if (event.targetInfo.type !== 'page') {
203+
await browserClient.send('Network.enable', protocolManager?.networkEnableOptions ?? DEFAULT_NETWORK_ENABLE_OPTIONS, event.sessionId)
204+
}
204205

205-
if (event.waitingForDebugger) {
206-
await browserClient.send('Runtime.runIfWaitingForDebugger', undefined, event.sessionId)
206+
if (event.waitingForDebugger) {
207+
await browserClient.send('Runtime.runIfWaitingForDebugger', undefined, event.sessionId)
208+
}
209+
} catch (error) {
210+
// it's possible that the target was closed before we could enable network and continue, in that case, just ignore
211+
debug('error attaching to target browser', error)
207212
}
208213
})
209214

packages/server/lib/browsers/cri-client.ts

+12-7
Original file line numberDiff line numberDiff line change
@@ -285,13 +285,18 @@ export const create = async ({
285285

286286
if (fullyManageTabs) {
287287
cri.on('Target.attachedToTarget', async (event) => {
288-
// Service workers get attached at the page and browser level. We only want to handle them at the browser level
289-
if (event.targetInfo.type !== 'service_worker' && event.targetInfo.type !== 'page') {
290-
await cri.send('Network.enable', protocolManager?.networkEnableOptions ?? DEFAULT_NETWORK_ENABLE_OPTIONS, event.sessionId)
291-
}
292-
293-
if (event.waitingForDebugger) {
294-
await cri.send('Runtime.runIfWaitingForDebugger', undefined, event.sessionId)
288+
try {
289+
// Service workers get attached at the page and browser level. We only want to handle them at the browser level
290+
if (event.targetInfo.type !== 'service_worker' && event.targetInfo.type !== 'page') {
291+
await cri.send('Network.enable', protocolManager?.networkEnableOptions ?? DEFAULT_NETWORK_ENABLE_OPTIONS, event.sessionId)
292+
}
293+
294+
if (event.waitingForDebugger) {
295+
await cri.send('Runtime.runIfWaitingForDebugger', undefined, event.sessionId)
296+
}
297+
} catch (error) {
298+
// it's possible that the target was closed before we could enable network and continue, in that case, just ignore
299+
debug('error attaching to target cri', error)
295300
}
296301
})
297302

packages/server/test/unit/browsers/browser-cri-client_spec.ts

+25
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,31 @@ describe('lib/browsers/cri-client', function () {
187187
expect(protocolManager.connectToBrowser).to.be.calledWith(client)
188188
})
189189

190+
it('creates a page client when the passed in url is found and notifies the protocol manager and fully managed tabs and attaching to target throws', async function () {
191+
const mockPageClient = {}
192+
const protocolManager: any = {
193+
connectToBrowser: sinon.stub().resolves(),
194+
}
195+
196+
send.withArgs('Target.getTargets').resolves({ targetInfos: [{ targetId: '1', url: 'http://foo.com' }, { targetId: '2', url: 'http://bar.com' }] })
197+
send.withArgs('Target.setDiscoverTargets', { discover: true })
198+
on.withArgs('Target.targetDestroyed', sinon.match.func)
199+
200+
send.withArgs('Network.enable').throws(new Error('ProtocolError: Inspected target navigated or closed'))
201+
202+
criClientCreateStub.withArgs({ target: '1', onAsynchronousError: onError, host: HOST, port: PORT, protocolManager, fullyManageTabs: true, browserClient: { on, send, close } }).resolves(mockPageClient)
203+
204+
const browserClient = await getClient({ protocolManager, fullyManageTabs: true })
205+
206+
const client = await browserClient.attachToTargetUrl('http://foo.com')
207+
208+
expect(client).to.be.equal(mockPageClient)
209+
expect(protocolManager.connectToBrowser).to.be.calledWith(client)
210+
211+
// This would throw if the error was not caught
212+
await on.withArgs('Target.attachedToTarget').args[0][1]({ targetInfo: { type: 'worker' } })
213+
})
214+
190215
it('retries when the passed in url is not found', async function () {
191216
sinon.stub(protocol, '_getDelayMsForRetry')
192217
.onFirstCall().returns(100)

packages/server/test/unit/browsers/cri-client_spec.ts

+8
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,14 @@ describe('lib/browsers/cri-client', function () {
8888
await expect(client.send(command, { depth: -1 })).to.be.rejectedWith(`${command} will not run as the target browser or tab CRI connection has crashed`)
8989
})
9090

91+
it('does not reject if attachToTarget work throws', async function () {
92+
criStub.send.withArgs('Network.enable').throws(new Error('ProtocolError: Inspected target navigated or closed'))
93+
await getClient({ host: '127.0.0.1', fullyManageTabs: true })
94+
95+
// This would throw if the error was not caught
96+
await criStub.on.withArgs('Target.attachedToTarget').args[0][1]({ targetInfo: { type: 'worker' } })
97+
})
98+
9199
context('retries', () => {
92100
([
93101
'WebSocket is not open',

0 commit comments

Comments
 (0)