@@ -9,9 +9,83 @@ import { PostMessageEvent } from '@metamask/post-message-stream';
99// @ts -expect-error Types are currently broken for this.
1010import WebViewHTML from '@metamask/snaps-execution-environments/dist/webpack/webview/index.html' ;
1111import { EmptyObject } from '@metamask/snaps-sdk' ;
12+ import {
13+ FALLBACK_MOCK_SERVER_PORT ,
14+ isE2E ,
15+ testConfig ,
16+ } from '../../util/test/utils' ;
1217
1318const styles = createStyles ( ) ;
1419
20+ const getE2ENetworkProxyInjection = ( mockServerPort : string ) : string => `
21+ (function() {
22+ var mockServerUrl = 'http://localhost:${ mockServerPort } ';
23+ var proxyPrefix = mockServerUrl + '/proxy?url=';
24+
25+ function toUrlString(url) {
26+ if (typeof url === 'string') {
27+ return url;
28+ }
29+ if (url && typeof url === 'object' && typeof url.url === 'string') {
30+ return url.url;
31+ }
32+ return String(url);
33+ }
34+
35+ function shouldProxy(url) {
36+ return (
37+ typeof url === 'string' &&
38+ (url.startsWith('http://') || url.startsWith('https://')) &&
39+ !url.includes('/proxy?url=') &&
40+ !url.includes('localhost:${ mockServerPort } ') &&
41+ !url.includes('127.0.0.1:${ mockServerPort } ') &&
42+ !url.includes('10.0.2.2:${ mockServerPort } ')
43+ );
44+ }
45+
46+ if (typeof fetch === 'function') {
47+ var originalFetch = fetch.bind(window);
48+ window.fetch = function(url, options) {
49+ var urlString = toUrlString(url);
50+ var finalUrl = shouldProxy(urlString)
51+ ? proxyPrefix + encodeURIComponent(urlString)
52+ : url;
53+ return originalFetch(finalUrl, options);
54+ };
55+ }
56+
57+ var OriginalXHR = window.XMLHttpRequest;
58+ if (typeof OriginalXHR === 'function') {
59+ window.XMLHttpRequest = function() {
60+ var xhr = new OriginalXHR();
61+ var originalOpen = xhr.open;
62+
63+ xhr.open = function(method, url) {
64+ var openArgs = Array.prototype.slice.call(arguments, 2);
65+ var finalUrl = shouldProxy(url)
66+ ? proxyPrefix + encodeURIComponent(url)
67+ : url;
68+ return originalOpen.call.apply(
69+ originalOpen,
70+ [this, method, finalUrl].concat(openArgs),
71+ );
72+ };
73+
74+ return xhr;
75+ };
76+
77+ try {
78+ Object.setPrototypeOf(window.XMLHttpRequest, OriginalXHR);
79+ Object.assign(window.XMLHttpRequest, OriginalXHR);
80+ window.XMLHttpRequest.prototype = OriginalXHR.prototype;
81+ } catch (e) {
82+ // No-op: this is best effort in the constrained WebView runtime.
83+ }
84+ }
85+ })();
86+ true;
87+ ` ;
88+
1589// This is a hack to allow us to asynchronously await the creation of the WebView.
1690// eslint-disable-next-line import/no-mutable-exports
1791export let createWebView : ( jobId : string ) => Promise < WebViewInterface > ;
@@ -107,6 +181,14 @@ export class SnapsExecutionWebView extends Component {
107181 }
108182
109183 render ( ) {
184+ const mockServerPort = String (
185+ testConfig . mockServerPort ?? FALLBACK_MOCK_SERVER_PORT ,
186+ ) ;
187+ const e2eWebViewNetworkProxyInjection = isE2E
188+ ? getE2ENetworkProxyInjection ( mockServerPort )
189+ : undefined ;
190+ const mixedContentMode = isE2E ? 'always' : undefined ;
191+
110192 return (
111193 < View style = { styles . container } >
112194 { Object . entries ( this . webViews ) . map ( ( [ key , { props } ] ) => (
@@ -119,6 +201,10 @@ export class SnapsExecutionWebView extends Component {
119201 onError = { props . onWebViewError }
120202 onLoadEnd = { props . onWebViewLoad }
121203 originWhitelist = { [ '*' ] }
204+ mixedContentMode = { mixedContentMode }
205+ injectedJavaScriptBeforeContentLoaded = {
206+ e2eWebViewNetworkProxyInjection
207+ }
122208 javaScriptEnabled
123209 webviewDebuggingEnabled = { __DEV__ }
124210 />
0 commit comments