diff --git a/CHANGELOG.md b/CHANGELOG.md index 123260aff..09620362f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ All notable changes to AET will be documented in this file. - [PR-480](https://github.com/Cognifide/aet/pull/480) Test summary stats on the main report page. ([#474](https://github.com/Cognifide/aet/issues/474)) - [PR-459](https://github.com/Cognifide/aet/pull/459) Print more meaningful error messages when suite.xml is malformed ([#436](https://github.com/Cognifide/aet/issues/436)) - [PR-517](https://github.com/Cognifide/aet/pull/517) Single URL rerun fixed for named URLs ([#487](https://github.com/Cognifide/aet/issues/487)) +- [PR-516](https://github.com/Cognifide/aet/pull/516) Added option to change headers added by Chrome instance. ([#515](https://github.com/Cognifide/aet/issues/515)) ## Version 3.2.2 diff --git a/api/jobs-api/src/main/java/com/cognifide/aet/job/api/collector/ProxyServerWrapper.java b/api/jobs-api/src/main/java/com/cognifide/aet/job/api/collector/ProxyServerWrapper.java index b3185b3da..38b502050 100644 --- a/api/jobs-api/src/main/java/com/cognifide/aet/job/api/collector/ProxyServerWrapper.java +++ b/api/jobs-api/src/main/java/com/cognifide/aet/job/api/collector/ProxyServerWrapper.java @@ -34,7 +34,7 @@ public interface ProxyServerWrapper { void setCaptureContent(boolean captureContent); - void addHeader(String name, String value); + void addHeader(String name, String value, Boolean override); void stop() throws ProxyException; diff --git a/core/jobs/src/main/java/com/cognifide/aet/job/common/modifiers/header/HeaderModifier.java b/core/jobs/src/main/java/com/cognifide/aet/job/common/modifiers/header/HeaderModifier.java index 11b60ef6c..a6d5135d6 100644 --- a/core/jobs/src/main/java/com/cognifide/aet/job/common/modifiers/header/HeaderModifier.java +++ b/core/jobs/src/main/java/com/cognifide/aet/job/common/modifiers/header/HeaderModifier.java @@ -30,12 +30,16 @@ public class HeaderModifier implements CollectorJob { private static final String PARAM_VALUE = "value"; + private static final String PARAM_OVERRIDE = "override"; + private final WebCommunicationWrapper webCommunicationWrapper; private String key; private String value; + private Boolean override; + public HeaderModifier(WebCommunicationWrapper webCommunicationWrapper) { this.webCommunicationWrapper = webCommunicationWrapper; } @@ -46,7 +50,7 @@ public CollectorStepResult collect() throws ProcessingException { if (!webCommunicationWrapper.isUseProxy()) { throw new ProcessingException("Cannot modify header without using proxy"); } - webCommunicationWrapper.getProxyServer().addHeader(key, value); + webCommunicationWrapper.getProxyServer().addHeader(key, value, override); webCommunicationWrapper.getHttpRequestExecutor().addHeader(key, value); return CollectorStepResult.newModifierResult(); } @@ -59,6 +63,11 @@ public void setParameters(Map params) throws ParametersException } else { throw new ParametersException("Missing Key or Value on Header Modifier"); } + if (params.containsKey(PARAM_OVERRIDE)) { + override = Boolean.parseBoolean(params.get(PARAM_OVERRIDE)); + } else { + override = false; + } } } diff --git a/core/jobs/src/test/java/com/cognifide/aet/job/common/modifiers/header/HeaderModifierTest.java b/core/jobs/src/test/java/com/cognifide/aet/job/common/modifiers/header/HeaderModifierTest.java index 191e034e1..65d20e1c0 100644 --- a/core/jobs/src/test/java/com/cognifide/aet/job/common/modifiers/header/HeaderModifierTest.java +++ b/core/jobs/src/test/java/com/cognifide/aet/job/common/modifiers/header/HeaderModifierTest.java @@ -58,7 +58,7 @@ public void testCollect() throws Exception { headerModifier.setParameters(ImmutableMap.of("key", "header", "value", "value1")); headerModifier.collect(); - verify(proxyServer).addHeader("header", "value1"); + verify(proxyServer).addHeader("header", "value1", false); verify(requestExecutor).addHeader("header", "value1"); } diff --git a/documentation/src/main/wiki/HeaderModifier.md b/documentation/src/main/wiki/HeaderModifier.md index 3ad2d473e..602a17f44 100644 --- a/documentation/src/main/wiki/HeaderModifier.md +++ b/documentation/src/main/wiki/HeaderModifier.md @@ -14,6 +14,11 @@ In order to use this modifier it must be declared before the open module in the | --------- | ----- | ----------- | --------- | | `key` | x | Key for the header | yes | | `value` | y | Value for the header | yes | +| `override` | `true`/`false` | Override option should be set at `true` when your want replace header added by Chrome instance, otherwise it should by `false` | no (default false) | + +Important note. + +When you want add another value to Accept header and leave the default value create by Chrome instance, you can use `override=false`. ##### Example Usage @@ -23,6 +28,9 @@ In order to use this modifier it must be declared before the open module in the ... +
+
... diff --git a/integration-tests/sample-site/src/main/webapp/sanity/modifiers/header/show_headers.jsp b/integration-tests/sample-site/src/main/webapp/sanity/modifiers/header/show_headers.jsp new file mode 100644 index 000000000..a9121cfac --- /dev/null +++ b/integration-tests/sample-site/src/main/webapp/sanity/modifiers/header/show_headers.jsp @@ -0,0 +1,41 @@ +<%-- + + AET + + Copyright (C) 2013 Cognifide Limited + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--%> +<%@ page import="java.util.*" %> + + + + Headers test + + + +

HTTP Request Headers Received

+ + <% Enumeration enumeration = request.getHeaderNames(); while (enumeration.hasMoreElements()) + { + String name=(String) enumeration.nextElement(); + String value = request.getHeader(name); %> + + + + + <% } %> +
<%=name %><%=value %>
+ + \ No newline at end of file diff --git a/integration-tests/sanity-functional/src/test/java/com/cognifide/aet/sanity/functional/HomePageTilesTest.java b/integration-tests/sanity-functional/src/test/java/com/cognifide/aet/sanity/functional/HomePageTilesTest.java index ed0c3a51c..7015c751b 100644 --- a/integration-tests/sanity-functional/src/test/java/com/cognifide/aet/sanity/functional/HomePageTilesTest.java +++ b/integration-tests/sanity-functional/src/test/java/com/cognifide/aet/sanity/functional/HomePageTilesTest.java @@ -29,9 +29,9 @@ @Modules(GuiceModule.class) public class HomePageTilesTest { - private static final int TESTS = 149; + private static final int TESTS = 152; - private static final int EXPECTED_TESTS_SUCCESS = 85; + private static final int EXPECTED_TESTS_SUCCESS = 88; private static final int EXPECTED_TESTS_CONDITIONALLY_PASSED = 11; diff --git a/integration-tests/sanity-functional/src/test/resources/features/filtering.feature b/integration-tests/sanity-functional/src/test/resources/features/filtering.feature index de70a55a8..a3fb34ee2 100644 --- a/integration-tests/sanity-functional/src/test/resources/features/filtering.feature +++ b/integration-tests/sanity-functional/src/test/resources/features/filtering.feature @@ -73,8 +73,8 @@ Feature: Tests Results Filtering Scenario: Filtering Tests Results: header Given I have opened sample tests report page When I search for tests containing "header" - Then There are 1 tiles visible - And Statistics text contains "1 ( 0 / 0 / 1 (0) / 0 )" + Then There are 4 tiles visible + And Statistics text contains "4 ( 0 / 0 / 4 (0) / 0 )" Scenario: Filtering Tests Results: sleep-modifier Given I have opened sample tests report page diff --git a/integration-tests/test-suite/partials/header.xml b/integration-tests/test-suite/partials/header.xml index 84997a938..bd1540654 100644 --- a/integration-tests/test-suite/partials/header.xml +++ b/integration-tests/test-suite/partials/header.xml @@ -38,5 +38,56 @@ + + +
+ + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + diff --git a/osgi-dependencies/proxy/src/main/java/com/cognifide/aet/proxy/RestProxyServer.java b/osgi-dependencies/proxy/src/main/java/com/cognifide/aet/proxy/RestProxyServer.java index 401344118..059d5fc3b 100644 --- a/osgi-dependencies/proxy/src/main/java/com/cognifide/aet/proxy/RestProxyServer.java +++ b/osgi-dependencies/proxy/src/main/java/com/cognifide/aet/proxy/RestProxyServer.java @@ -17,31 +17,27 @@ import com.cognifide.aet.job.api.collector.ProxyServerWrapper; import com.cognifide.aet.proxy.exceptions.UnableToAddHeaderException; +import com.cognifide.aet.proxy.headers.HeaderRequestFactory; import com.github.detro.browsermobproxyclient.BMPCProxy; import com.github.detro.browsermobproxyclient.exceptions.BMPCUnableToConnectException; import com.google.gson.GsonBuilder; -import java.io.IOException; -import java.net.UnknownHostException; -import java.util.Date; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.browsermob.core.har.Har; -import org.json.JSONObject; import org.openqa.selenium.Proxy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class RestProxyServer implements ProxyServerWrapper { +import java.io.IOException; +import java.util.Date; - private static final String HTTP = "http"; +public class RestProxyServer implements ProxyServerWrapper { public static final int STATUS_CODE_OK = 200; - private BMPCProxy server; + private final BMPCProxy server; private boolean captureContent; @@ -49,15 +45,18 @@ public class RestProxyServer implements ProxyServerWrapper { private RestProxyManager proxyManager; + private final HeaderRequestFactory requestFactory; + private static final Logger LOGGER = LoggerFactory.getLogger(RestProxyServer.class); public RestProxyServer(BMPCProxy bmpcProxy, RestProxyManager restProxyManager) { this.server = bmpcProxy; this.proxyManager = restProxyManager; + this.requestFactory = new HeaderRequestFactory(bmpcProxy); } @Override - public Proxy seleniumProxy() throws UnknownHostException { + public Proxy seleniumProxy() { return server.asSeleniumProxy() .setHttpProxy(String.format("%s:%d", proxyManager.getServer(), getPort())) .setSslProxy(String.format("%s:%d", proxyManager.getServer(), getPort())); @@ -95,18 +94,10 @@ public void setCaptureContent(boolean captureContent) { } @Override - public void addHeader(String name, String value) { + public void addHeader(String name, String value, Boolean override) { CloseableHttpClient httpClient = HttpClients.createSystem(); try { - URIBuilder uriBuilder = new URIBuilder().setScheme(HTTP).setHost(server.getAPIHost()) - .setPort(server.getAPIPort()); - // Request BMP to add header - HttpPost request = new HttpPost(uriBuilder.setPath( - String.format("/proxy/%d/headers", server.getProxyPort())).build()); - request.setHeader("Content-Type", "application/json"); - JSONObject json = new JSONObject(); - json.put(name, value); - request.setEntity(new StringEntity(json.toString())); + HttpPost request = requestFactory.create(name, value, override); // Execute request CloseableHttpResponse response = httpClient.execute(request); int statusCode = response.getStatusLine().getStatusCode(); @@ -133,5 +124,4 @@ public void stop() { server.close(); proxyManager.detach(this); } - } diff --git a/osgi-dependencies/proxy/src/main/java/com/cognifide/aet/proxy/headers/AddHeader.java b/osgi-dependencies/proxy/src/main/java/com/cognifide/aet/proxy/headers/AddHeader.java new file mode 100644 index 000000000..28685dd3e --- /dev/null +++ b/osgi-dependencies/proxy/src/main/java/com/cognifide/aet/proxy/headers/AddHeader.java @@ -0,0 +1,53 @@ +/** + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package com.cognifide.aet.proxy.headers; + +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.entity.StringEntity; +import org.json.JSONObject; + +import java.io.UnsupportedEncodingException; +import java.net.URISyntaxException; + +public class AddHeader implements HeaderRequestStrategy { + + private final String apiHost; + + private final int apiPort; + + private final int proxyPort; + + public AddHeader(String apiHost, int apiPort, int proxyPort) { + this.apiHost = apiHost; + this.apiPort = apiPort; + this.proxyPort = proxyPort; + } + + @Override + public HttpPost createRequest(String name, String value) + throws URISyntaxException, UnsupportedEncodingException { + URIBuilder uriBuilder = new URIBuilder().setScheme("http") + .setHost(apiHost).setPort(apiPort); + HttpPost request = new HttpPost(uriBuilder.setPath( + String.format("/proxy/%d/headers", proxyPort)).build()); + request.setHeader("Content-Type", "application/json"); + JSONObject json = new JSONObject(); + json.put(name, value); + request.setEntity(new StringEntity(json.toString())); + return request; + } +} diff --git a/osgi-dependencies/proxy/src/main/java/com/cognifide/aet/proxy/headers/HeaderRequestFactory.java b/osgi-dependencies/proxy/src/main/java/com/cognifide/aet/proxy/headers/HeaderRequestFactory.java new file mode 100644 index 000000000..94ea72f08 --- /dev/null +++ b/osgi-dependencies/proxy/src/main/java/com/cognifide/aet/proxy/headers/HeaderRequestFactory.java @@ -0,0 +1,43 @@ +/** + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package com.cognifide.aet.proxy.headers; + +import com.github.detro.browsermobproxyclient.BMPCProxy; +import org.apache.http.client.methods.HttpPost; + +import java.io.UnsupportedEncodingException; +import java.net.URISyntaxException; + +public class HeaderRequestFactory { + + private final BMPCProxy server; + + public HeaderRequestFactory(BMPCProxy server) { + this.server = server; + } + + public HttpPost create(String name, String value, Boolean override) throws UnsupportedEncodingException, URISyntaxException { + HeaderRequestStrategy headerRequestStrategy; + if (override) { + headerRequestStrategy = new OverrideHeader(server.getAPIHost(), server.getAPIPort(), + server.getProxyPort()); + } else { + headerRequestStrategy = new AddHeader(server.getAPIHost(), server.getAPIPort(), + server.getProxyPort()); + } + return headerRequestStrategy.createRequest(name, value); + } +} diff --git a/osgi-dependencies/proxy/src/main/java/com/cognifide/aet/proxy/headers/HeaderRequestStrategy.java b/osgi-dependencies/proxy/src/main/java/com/cognifide/aet/proxy/headers/HeaderRequestStrategy.java new file mode 100644 index 000000000..7738a7994 --- /dev/null +++ b/osgi-dependencies/proxy/src/main/java/com/cognifide/aet/proxy/headers/HeaderRequestStrategy.java @@ -0,0 +1,25 @@ +/** + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package com.cognifide.aet.proxy.headers; + +import org.apache.http.client.methods.HttpPost; + +import java.io.UnsupportedEncodingException; +import java.net.URISyntaxException; + +public interface HeaderRequestStrategy { + HttpPost createRequest(String name, String value) throws URISyntaxException, UnsupportedEncodingException; +} diff --git a/osgi-dependencies/proxy/src/main/java/com/cognifide/aet/proxy/headers/OverrideHeader.java b/osgi-dependencies/proxy/src/main/java/com/cognifide/aet/proxy/headers/OverrideHeader.java new file mode 100644 index 000000000..03ad9b117 --- /dev/null +++ b/osgi-dependencies/proxy/src/main/java/com/cognifide/aet/proxy/headers/OverrideHeader.java @@ -0,0 +1,53 @@ +/** + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package com.cognifide.aet.proxy.headers; + +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.entity.StringEntity; + +import java.io.UnsupportedEncodingException; +import java.net.URISyntaxException; + +public class OverrideHeader implements HeaderRequestStrategy { + + private final String apiHost; + + private final int apiPort; + + private final int proxyPort; + + public OverrideHeader(String apiHost, int apiPort, int proxyPort) { + this.apiHost = apiHost; + this.apiPort = apiPort; + this.proxyPort = proxyPort; + } + + @Override + public HttpPost createRequest(String name, String value) + throws URISyntaxException, UnsupportedEncodingException { + URIBuilder uriBuilder = new URIBuilder().setScheme("http") + .setHost(apiHost).setPort(apiPort); + HttpPost request = new HttpPost(uriBuilder.setPath( + String.format("/proxy/%d/filter/request", proxyPort)).build()); + request.setHeader("Content-Type", "text/plain"); + String data = String.format( + "request.headers().remove('%s'); request.headers().add('%s', '%s');", + name, name, value); + request.setEntity(new StringEntity(data)); + return request; + } +}