-
Notifications
You must be signed in to change notification settings - Fork 3.4k
fix: Browser will freeze when sync request is intercepted #32925
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
alexsch01
wants to merge
31
commits into
cypress-io:develop
Choose a base branch
from
alexsch01:fix-browser-freeze
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+203
−32
Open
Changes from all commits
Commits
Show all changes
31 commits
Select commit
Hold shift + click to select a range
dc16aef
fix: Browser will freeze when sync request is intercepted
alexsch01 9182b4e
Update CHANGELOG.md
alexsch01 4801766
Update CHANGELOG.md
alexsch01 7b4f2e7
prevent cross origin cookies from breaking sync requests
alexsch01 02f6105
Update xmlHttpRequest.ts
alexsch01 7f0d6c6
Update xmlHttpRequest.ts
alexsch01 12a25e4
fix lint
alexsch01 6a21ef2
Merge branch 'develop' into fix-browser-freeze
alexsch01 a837527
Update intercepted-request.ts
alexsch01 3cdaa5f
Update response-middleware.ts
alexsch01 c27f137
Merge branch 'develop' into fix-browser-freeze
alexsch01 247da30
grammar fix
alexsch01 6664756
better warning
alexsch01 a9e67e1
Blank
alexsch01 5a65b0c
Update intercepted-request.ts
alexsch01 7d4a48b
Update response-middleware.ts
alexsch01 88c83e1
Update xmlHttpRequest.ts
alexsch01 29b4dc7
Merge branch 'develop' into fix-browser-freeze
jennifer-shehane 775edee
Alexsch01 patch 1
alexsch01 844904d
Update xmlHttpRequest.ts
alexsch01 be6a22f
Update main.js
alexsch01 cda831d
this is correct now
alexsch01 f846e8e
move sync intercept and move patches
mschile da1d38f
Merge branch 'develop' into fix-browser-freeze
jennifer-shehane 931b4fe
add unit test for proxy
alexsch01 82707fc
Create intercept_sync_request.cy.ts
alexsch01 cfabc45
Create sync_request_with_cookie.cy.ts
alexsch01 ad809b6
lint
alexsch01 48807a6
Update intercept_sync_request.cy.ts
alexsch01 8adc9d1
Update intercept_sync_request.cy.ts
alexsch01 39a2fa3
Update sync_request_with_cookie.cy.ts
alexsch01 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
packages/driver/cypress/e2e/e2e/intercept_sync_request.cy.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| // https://github.com/cypress-io/cypress/pull/32925 | ||
| describe('intercept sync request', () => { | ||
| it('completes all the way with route handler', () => { | ||
| cy.intercept('/app', { | ||
| body: ` | ||
| <!DOCTYPE html> | ||
| <html> | ||
| <head> | ||
| <title>Sync Request</title> | ||
| </head> | ||
| <body> | ||
| <div> | ||
| <button id="sync-request-button">Test Sync Request</button> | ||
| <div id="counter"></div> | ||
| </div> | ||
| <script> | ||
| const button = document.querySelector('#sync-request-button') | ||
| button.addEventListener('click', () => { | ||
| let xhr = new window.XMLHttpRequest() | ||
| xhr.open('GET', '/', false) | ||
| xhr.onload = () => console.log(xhr.status) | ||
| xhr.send() | ||
| }) | ||
| let count = 0 | ||
| setInterval(() => { | ||
| document.querySelector('#counter').innerHTML = count | ||
| count++ | ||
| }, 100) | ||
| </script> | ||
| </body> | ||
| </html> | ||
| `, | ||
| }) | ||
|
|
||
| cy.intercept('/', () => {}) | ||
| cy.visit('/app') | ||
| cy.get('#sync-request-button').click() | ||
| cy.wrap(0).should('eq', 0) | ||
| }) | ||
| }) |
45 changes: 45 additions & 0 deletions
45
packages/driver/cypress/e2e/e2e/origin/sync_request_with_cookie.cy.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| // https://github.com/cypress-io/cypress/pull/32925 | ||
| describe('Sync Request in cy.origin that sets cookie', () => { | ||
| it('passes', { browser: '!webkit' }, () => { | ||
| cy.intercept('https://foo.site.com', { | ||
| body: ` | ||
| <!DOCTYPE html> | ||
| <html> | ||
| <body> | ||
| Page 1 / 2 | ||
| </body> | ||
| </html> | ||
| `, | ||
| }) | ||
|
|
||
| cy.visit('https://foo.site.com') | ||
|
|
||
| cy.intercept('https://test.site.com/sync', { | ||
| headers: { | ||
| 'set-cookie': 'TEST=foo', | ||
| }, | ||
| body: '', | ||
| }) | ||
|
|
||
| cy.intercept('https://test.site.com/bar', { | ||
| body: ` | ||
| <!DOCTYPE html> | ||
| <html> | ||
| <body> | ||
| Page 2 / 2 | ||
| <script> | ||
| let xhr = new window.XMLHttpRequest() | ||
| xhr.open('GET', '/sync', false) | ||
| xhr.send() | ||
| </script> | ||
| </body> | ||
| </html> | ||
| `, | ||
| }) | ||
|
|
||
| cy.origin('https://test.site.com', () => { | ||
| cy.visit('https://test.site.com/bar') | ||
| cy.wrap(0).should('eq', 0) | ||
| }) | ||
| }) | ||
| }) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
51 changes: 51 additions & 0 deletions
51
packages/runner/injection/patches/cross-origin/xmlHttpRequest.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| import { captureFullRequestUrl, requestSentWithCredentials } from './utils' | ||
|
|
||
| export const patchXmlHttpRequest = (window: Window) => { | ||
| // intercept method calls and add cypress headers to determine cookie applications in the proxy | ||
| // for simulated top | ||
|
|
||
| const originalXmlHttpRequestOpen = window.XMLHttpRequest.prototype.open | ||
| const originalXmlHttpRequestSend = window.XMLHttpRequest.prototype.send | ||
|
|
||
| window.XMLHttpRequest.prototype.open = function (...args) { | ||
| try { | ||
| // since the send method does NOT have access to the arguments passed into open or have the request information, | ||
| // we need to store a reference here to what we need in the send method | ||
| this._url = captureFullRequestUrl(args[1], window) | ||
| } finally { | ||
| const result = originalXmlHttpRequestOpen.apply(this, args as any) | ||
|
|
||
| if (args.length > 2 && !args[2]) { | ||
| this.setRequestHeader('x-cypress-is-sync-request', 'true') | ||
| this._isSyncRequest = true | ||
| } else { | ||
| this._isSyncRequest = false | ||
| } | ||
|
|
||
| return result | ||
| } | ||
| } | ||
|
|
||
| window.XMLHttpRequest.prototype.send = function (...args) { | ||
| // if the request is sync, we cannot wait on the requestSentWithCredentials | ||
| // function call since the sync request is blocking. | ||
| if (this._isSyncRequest) { | ||
| return originalXmlHttpRequestSend.apply(this, args) | ||
| } | ||
|
|
||
| return (async () => { | ||
| try { | ||
| // if the option is specified, communicate it to the the server to the proxy can make the request aware if it needs to potentially apply cross origin cookies | ||
| // if the option isn't set, we can imply the default as we know the "resourceType" in the proxy | ||
| await requestSentWithCredentials({ | ||
| url: this._url, | ||
| resourceType: 'xhr', | ||
| credentialStatus: this.withCredentials, | ||
| }) | ||
| } finally { | ||
| // if our internal logic errors for whatever reason, do NOT block the end user and continue the request | ||
| return originalXmlHttpRequestSend.apply(this, args) | ||
| } | ||
| })() | ||
| } | ||
alexsch01 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,34 +1,13 @@ | ||
| import { captureFullRequestUrl, requestSentWithCredentials } from './utils' | ||
|
|
||
| export const patchXmlHttpRequest = (window: Window) => { | ||
| // intercept method calls and add cypress headers to determine cookie applications in the proxy | ||
| // for simulated top | ||
|
|
||
| const originalXmlHttpRequestOpen = window.XMLHttpRequest.prototype.open | ||
| const originalXmlHttpRequestSend = window.XMLHttpRequest.prototype.send | ||
|
|
||
| window.XMLHttpRequest.prototype.open = function (...args) { | ||
| try { | ||
| // since the send method does NOT have access to the arguments passed into open or have the request information, | ||
| // we need to store a reference here to what we need in the send method | ||
| this._url = captureFullRequestUrl(args[1], window) | ||
| } finally { | ||
| return originalXmlHttpRequestOpen.apply(this, args as any) | ||
| } | ||
| } | ||
| const result = originalXmlHttpRequestOpen.apply(this, args) | ||
|
|
||
| window.XMLHttpRequest.prototype.send = async function (...args) { | ||
| try { | ||
| // if the option is specified, communicate it to the the server to the proxy can make the request aware if it needs to potentially apply cross origin cookies | ||
| // if the option isn't set, we can imply the default as we know the "resourceType" in the proxy | ||
| await requestSentWithCredentials({ | ||
| url: this._url, | ||
| resourceType: 'xhr', | ||
| credentialStatus: this.withCredentials, | ||
| }) | ||
| } finally { | ||
| // if our internal logic errors for whatever reason, do NOT block the end user and continue the request | ||
| return originalXmlHttpRequestSend.apply(this, args) | ||
| if (args.length > 2 && !args[2]) { | ||
| this.setRequestHeader('x-cypress-is-sync-request', 'true') | ||
| } | ||
|
|
||
| return result | ||
| } | ||
| } |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.