Skip to content

Commit a78b998

Browse files
[java] Added fix to intercept PUT request
Co-authored-by: Puja Jagani <[email protected]>
1 parent be30b62 commit a78b998

2 files changed

Lines changed: 204 additions & 0 deletions

File tree

java/src/org/openqa/selenium/remote/http/HttpMethod.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,6 @@ public enum HttpMethod {
2121
DELETE,
2222
GET,
2323
POST,
24+
PUT,
2425
OPTIONS
2526
}
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
// Licensed to the Software Freedom Conservancy (SFC) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The SFC licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package org.openqa.selenium.devtools;
19+
20+
import org.junit.After;
21+
import org.junit.Before;
22+
import org.junit.BeforeClass;
23+
import org.junit.Test;
24+
import org.openqa.selenium.JavascriptExecutor;
25+
import org.openqa.selenium.WebDriver;
26+
import org.openqa.selenium.environment.webserver.NettyAppServer;
27+
import org.openqa.selenium.remote.http.*;
28+
import org.openqa.selenium.testing.drivers.Browser;
29+
import org.openqa.selenium.testing.drivers.WebDriverBuilder;
30+
31+
import java.net.MalformedURLException;
32+
import java.net.URL;
33+
import java.util.concurrent.atomic.AtomicBoolean;
34+
35+
import static org.assertj.core.api.Assertions.assertThat;
36+
import static org.assertj.core.api.Assumptions.assumeThat;
37+
import static org.openqa.selenium.remote.http.Contents.utf8String;
38+
import static org.openqa.selenium.testing.Safely.safelyCall;
39+
import static org.openqa.selenium.testing.TestUtilities.isFirefoxVersionOlderThan;
40+
41+
public class NetworkInterceptorRestTest {
42+
43+
private NettyAppServer appServer;
44+
private WebDriver driver;
45+
private NetworkInterceptor interceptor;
46+
47+
@BeforeClass
48+
public static void shouldTestBeRunAtAll() {
49+
// Until Firefox can initialise the Fetch domain, we need this check
50+
assumeThat(Browser.detect()).isNotEqualTo(Browser.FIREFOX);
51+
assumeThat(Boolean.getBoolean("selenium.skiptest")).isFalse();
52+
}
53+
54+
@Before
55+
public void setup() {
56+
driver = new WebDriverBuilder().get();
57+
58+
assumeThat(driver).isInstanceOf(HasDevTools.class);
59+
assumeThat(isFirefoxVersionOlderThan(87, driver)).isFalse();
60+
61+
62+
Route route = Route.matching(req -> req.getMethod() == HttpMethod.OPTIONS)
63+
.to(() -> req -> new HttpResponse()
64+
.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE")
65+
.addHeader("Access-Control-Allow-Origin", "*"));
66+
67+
appServer = new NettyAppServer(route);
68+
appServer.start();
69+
}
70+
71+
@After
72+
public void tearDown() {
73+
safelyCall(
74+
() -> interceptor.close(),
75+
() -> driver.quit(),
76+
() -> appServer.stop());
77+
}
78+
79+
@Test
80+
public void shouldInterceptPutRequest() throws MalformedURLException {
81+
AtomicBoolean seen = new AtomicBoolean(false);
82+
interceptor = new NetworkInterceptor(
83+
driver,
84+
Route.matching(req -> (req.getMethod() == HttpMethod.PUT))
85+
.to(() -> req -> {
86+
seen.set(true);
87+
return new HttpResponse()
88+
.setStatus(200)
89+
.addHeader("Access-Control-Allow-Origin", "*")
90+
.setContent(utf8String("Received response for PUT"));
91+
}));
92+
93+
JavascriptExecutor js = (JavascriptExecutor) driver;
94+
Object response = js.executeAsyncScript(
95+
"var url = arguments[0];" +
96+
"var callback = arguments[arguments.length - 1];" +
97+
"var xhr = new XMLHttpRequest();" +
98+
"xhr.open('PUT', url, true);" +
99+
"xhr.onload = function() {" +
100+
" if (xhr.readyState == 4) {" +
101+
" callback(xhr.responseText);" +
102+
" }" +
103+
"};" +
104+
"xhr.send('Hey');", new URL(appServer.whereIs("/")).toString());
105+
106+
assertThat(seen.get()).isTrue();
107+
assertThat(response.toString()).contains("Received response for PUT");
108+
}
109+
110+
@Test
111+
public void shouldInterceptPostRequest() throws MalformedURLException {
112+
AtomicBoolean seen = new AtomicBoolean(false);
113+
interceptor = new NetworkInterceptor(
114+
driver,
115+
Route.matching(req -> (req.getMethod() == HttpMethod.POST))
116+
.to(() -> req -> {
117+
seen.set(true);
118+
return new HttpResponse()
119+
.setStatus(200)
120+
.addHeader("Access-Control-Allow-Origin", "*")
121+
.setContent(utf8String("Received response for POST"));
122+
}));
123+
124+
JavascriptExecutor js = (JavascriptExecutor) driver;
125+
Object response = js.executeAsyncScript(
126+
"var url = arguments[0];" +
127+
"var callback = arguments[arguments.length - 1];" +
128+
"var xhr = new XMLHttpRequest();" +
129+
"xhr.open('POST', url, true);" +
130+
"xhr.onload = function() {" +
131+
" if (xhr.readyState == 4) {" +
132+
" callback(xhr.responseText);" +
133+
" }" +
134+
"};" +
135+
"xhr.send('Hey');", new URL(appServer.whereIs("/")).toString());
136+
137+
assertThat(seen.get()).isTrue();
138+
assertThat(response.toString()).contains("Received response for POST");
139+
}
140+
141+
@Test
142+
public void shouldInterceptDeleteRequest() throws MalformedURLException {
143+
AtomicBoolean seen = new AtomicBoolean(false);
144+
interceptor = new NetworkInterceptor(
145+
driver,
146+
Route.matching(req -> (req.getMethod() == HttpMethod.DELETE))
147+
.to(() -> req -> {
148+
seen.set(true);
149+
return new HttpResponse()
150+
.setStatus(200)
151+
.addHeader("Access-Control-Allow-Origin", "*")
152+
.setContent(utf8String("Received response for DELETE"));
153+
}));
154+
155+
JavascriptExecutor js = (JavascriptExecutor) driver;
156+
Object response = js.executeAsyncScript(
157+
"var url = arguments[0];" +
158+
"var callback = arguments[arguments.length - 1];" +
159+
"var xhr = new XMLHttpRequest();" +
160+
"xhr.open('DELETE', url, true);" +
161+
"xhr.onload = function() {" +
162+
" if (xhr.readyState == 4) {" +
163+
" callback(xhr.responseText);" +
164+
" }" +
165+
"};" +
166+
"xhr.send('Hey');", new URL(appServer.whereIs("/")).toString());
167+
168+
assertThat(seen.get()).isTrue();
169+
assertThat(response.toString()).contains("Received response for DELETE");
170+
}
171+
172+
@Test
173+
public void shouldInterceptGetRequest() throws MalformedURLException {
174+
AtomicBoolean seen = new AtomicBoolean(false);
175+
interceptor = new NetworkInterceptor(
176+
driver,
177+
Route.matching(req -> (req.getMethod() == HttpMethod.GET))
178+
.to(() -> req -> {
179+
seen.set(true);
180+
return new HttpResponse()
181+
.setStatus(200)
182+
.addHeader("Access-Control-Allow-Origin", "*")
183+
.setContent(utf8String("Received response for GET"));
184+
}));
185+
186+
JavascriptExecutor js = (JavascriptExecutor) driver;
187+
Object response = js.executeAsyncScript(
188+
"var url = arguments[0];" +
189+
"var callback = arguments[arguments.length - 1];" +
190+
"var xhr = new XMLHttpRequest();" +
191+
"xhr.open('GET', url, true);" +
192+
"xhr.onload = function() {" +
193+
" if (xhr.readyState == 4) {" +
194+
" callback(xhr.responseText);" +
195+
" }" +
196+
"};" +
197+
"xhr.send();", new URL(appServer.whereIs("/")).toString());
198+
199+
assertThat(seen.get()).isTrue();
200+
assertThat(response.toString()).contains("Received response for GET");
201+
}
202+
203+
}

0 commit comments

Comments
 (0)