kazurayam / BrowserMobProxyInKatalonStudio

a sample Katalon Studio project that create a HAR file using BrowserMob proxy
https://forum.katalon.com/t/sample-usage-of-browsermob-proxy-in-katalon-studio/83322
0 stars 1 forks source link

a way to abort BrowserMob Proxy Server process while a conversion between browser and HTTP server is ongoing #13

Closed kazurayam closed 1 month ago

kazurayam commented 1 month ago

Here is a post in Katalon Forum which talks about the case where Katalon Studio detected a Connection Reset

https://forum.katalon.com/t/how-to-handle-exception-or-error-occured-due-to-sending-request-to-blocked-site/137317

Such case is difficult to reproduce because I need a broken HTTP server, which is difficult to intentionally implement.

An idea has come up to @kazurayam. Let Katalon Test talk to a HTTP server through BrowserMob Proxy. And Let the HTTP server waits long seconds (eg 60 secs) without responding. In this situation, I will shutdown the process of proxy. Then the client (Katalon test) will receive a "Connection Reset" from the local OS (in my case, Mac).

I need a way to start a BrowserMob proxy process with option --timer 10secs, which let the process to shutdown in 10 secs.

kazurayam commented 1 month ago

Why not add a small Test case stopBmpServer which just does

GlobalVariable.BrowserMobProxyServer.abort()

Then you can stop the server process whenever during other test case is running

https://javadoc.io/static/net.lightbody.bmp/browsermob-core/2.1.5/net/lightbody/bmp/BrowserMobProxy.html

kazurayam commented 1 month ago

Added TSx, which runs a new Test Case TestStuff2_abort_proxy.

It has a code section like this

def timer = new Timer()
if (GlobalVariable.BrowserMobProxyServer != null) {
    def task = timer.runAfter(5000) {
        GlobalVariable.BrowserMobProxyServer.abort()
        GlobalVariable.BrowserMobProxyServer = null
        println "Actually executed at ${new Date()}."
    }
    println "Current date is ${new Date()}. Task is executed at ${new Date(task.scheduledExecutionTime())}."
}

String url = "http://127.0.0.1:3000/dump"

try {
    status = getResponseStatus(url)
} catch(Exception ex) {
    println('in catch')
}

It sets a Timer. When the timer expired after 5secs, it will call BrowserMobProxyServer.abort() method.

https://javadoc.io/static/net.lightbody.bmp/browsermob-core/2.1.5/net/lightbody/bmp/BrowserMobProxy.html#abort--

kazurayam commented 1 month ago

When I ran the TSx, I saw output in the console like this

2024-07-16 17:08:54.674 INFO  c.k.katalon.core.main.TestSuiteExecutor  - START Test Suites/TSx
2024-07-16 17:08:54.804 INFO  c.k.katalon.core.main.TestSuiteExecutor  - hostName = kazuakiurayama - localhost
2024-07-16 17:08:54.807 INFO  c.k.katalon.core.main.TestSuiteExecutor  - os = Mac OS X 64bit
2024-07-16 17:08:54.812 INFO  c.k.katalon.core.main.TestSuiteExecutor  - hostAddress = 127.0.0.1
2024-07-16 17:08:54.817 INFO  c.k.katalon.core.main.TestSuiteExecutor  - katalonVersion = 9.0.0.212
2024-07-16 17:08:55.063 INFO  c.k.katalon.core.main.TestCaseExecutor   - --------------------
2024-07-16 17:08:55.063 INFO  c.k.katalon.core.main.TestCaseExecutor   - START Test Cases/startProxy_WebUI.openBrowser
2024-07-16 17:08:57.074 INFO  k.k.c.m.CustomKeywordDelegatingMetaClass - com.kazurayam.ks.BrowserMobProxyManager.startupBmpServer is PASSED
2024-07-16 17:08:57.682 INFO  c.k.k.core.webui.driver.DriverFactory    - Starting 'Chrome' driver
7月 16, 2024 5:08:57 午後 org.openqa.selenium.remote.DesiredCapabilities chrome
情報: Using `new ChromeOptions()` is preferred to `DesiredCapabilities.chrome()`
2024-07-16 17:08:57.692 INFO  c.k.k.c.w.util.WebDriverPropertyUtil     - User set preference: ['acceptInsecureCerts', 'true']
2024-07-16 17:08:57.694 INFO  c.k.k.c.w.util.WebDriverPropertyUtil     - User set preference: ['acceptSslCerts', 'true']
2024-07-16 17:08:57.695 INFO  c.k.k.c.w.util.WebDriverPropertyUtil     - User set preference: ['proxy', 'Proxy(manual, http=localhost:58014, ssl=localhost:58014)']
2024-07-16 17:08:57.732 INFO  c.k.k.core.webui.driver.DriverFactory    - Action delay is set to 0 milliseconds
Starting ChromeDriver 126.0.6478.126 (d36ace6122e0a59570e258d82441395206d60e1c-refs/branch-heads/6478@{#1591}) on port 20213
Only local connections are allowed.
Please see https://chromedriver.chromium.org/security-considerations for suggestions on keeping ChromeDriver safe.
ChromeDriver was started successfully.
7月 16, 2024 5:09:01 午後 org.openqa.selenium.remote.ProtocolHandshake createSession
情報: Detected dialect: W3C
2024-07-16 17:09:01.684 INFO  c.k.k.core.webui.driver.DriverFactory    - sessionId = 52ed083e23ec5f8dafbcff9277987cbe
2024-07-16 17:09:01.753 INFO  c.k.k.core.webui.driver.DriverFactory    - browser = Chrome 126.0.0.0
2024-07-16 17:09:01.771 INFO  c.k.k.core.webui.driver.DriverFactory    - platform = Mac OS X
2024-07-16 17:09:01.792 INFO  c.k.k.core.webui.driver.DriverFactory    - seleniumVersion = 3.141.59
2024-07-16 17:09:01.820 INFO  c.k.k.core.webui.driver.DriverFactory    - proxyInformation = ProxyInformation { proxyOption=NO_PROXY, proxyServerType=HTTP, username=, password=********, proxyServerAddress=, proxyServerPort=0, executionList="", isApplyToDesiredCapabilities=true }
2024-07-16 17:09:01.942 INFO  c.k.katalon.core.main.TestCaseExecutor   - END Test Cases/startProxy_WebUI.openBrowser
2024-07-16 17:09:01.966 INFO  c.k.katalon.core.main.TestCaseExecutor   - --------------------
2024-07-16 17:09:01.966 INFO  c.k.katalon.core.main.TestCaseExecutor   - START Test Cases/TestStuff2_abort_proxy
Current date is Tue Jul 16 17:09:02 JST 2024. Task is executed at Tue Jul 16 17:09:07 JST 2024.
requesting on URL: http://127.0.0.1:3000/dump
2024-07-16 17:09:04.299 ERROR c.k.k.core.keyword.internal.KeywordMain  - ❌ Unable to send request (Root cause: com.kms.katalon.core.webservice.exception.SendRequestException: org.apache.http.conn.HttpHostConnectException: Connect to 127.0.0.1:3000 [/127.0.0.1] failed: Connection refused
    at com.kms.katalon.core.webservice.common.HttpUtil.sendRequest(HttpUtil.java:174)
    at com.kms.katalon.core.webservice.common.BasicRequestor.send(BasicRequestor.java:58)
    at com.kms.katalon.core.webservice.helper.WebServiceCommonHelper.sendRequest(WebServiceCommonHelper.java:55)
    at com.kms.katalon.core.webservice.keyword.builtin.SendRequestKeyword$_sendRequest_closure1.doCall(SendRequestKeyword.groovy:40)
    at com.kms.katalon.core.webservice.keyword.builtin.SendRequestKeyword$_sendRequest_closure1.call(SendRequestKeyword.groovy)
    at com.kms.katalon.core.keyword.internal.KeywordMain.runKeyword(KeywordMain.groovy:75)
    at com.kms.katalon.core.webservice.keyword.builtin.SendRequestKeyword.sendRequest(SendRequestKeyword.groovy:38)
    at com.kms.katalon.core.webservice.keyword.builtin.SendRequestKeyword.execute(SendRequestKeyword.groovy:33)
    at com.kms.katalon.core.keyword.internal.KeywordExecutor.executeKeywordForPlatform(KeywordExecutor.groovy:74)
    at com.kms.katalon.core.webservice.keyword.WSBuiltInKeywords.sendRequest(WSBuiltInKeywords.groovy:41)
    at TestStuff2_abort_proxy.getResponseStatus(TestStuff2_abort_proxy:36)
    at TestStuff2_abort_proxy.run(TestStuff2_abort_proxy:21)
    at com.kms.katalon.core.main.ScriptEngine.run(ScriptEngine.java:194)
    at com.kms.katalon.core.main.ScriptEngine.runScriptAsRawText(ScriptEngine.java:119)
    at com.kms.katalon.core.main.TestCaseExecutor.runScript(TestCaseExecutor.java:448)
    at com.kms.katalon.core.main.TestCaseExecutor.doExecute(TestCaseExecutor.java:439)
    at com.kms.katalon.core.main.TestCaseExecutor.processExecutionPhase(TestCaseExecutor.java:418)
    at com.kms.katalon.core.main.TestCaseExecutor.accessMainPhase(TestCaseExecutor.java:410)
    at com.kms.katalon.core.main.TestCaseExecutor.execute(TestCaseExecutor.java:285)
    at com.kms.katalon.core.common.CommonExecutor.accessTestCaseMainPhase(CommonExecutor.java:65)
    at com.kms.katalon.core.main.TestSuiteExecutor.accessTestSuiteMainPhase(TestSuiteExecutor.java:148)
    at com.kms.katalon.core.main.TestSuiteExecutor.execute(TestSuiteExecutor.java:106)
    at com.kms.katalon.core.main.TestCaseMain.startTestSuite(TestCaseMain.java:187)
    at TempTestSuite1721117329040.run(TempTestSuite1721117329040.groovy:36)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
Caused by: org.apache.http.conn.HttpHostConnectException: Connect to 127.0.0.1:3000 [/127.0.0.1] failed: Connection refused
    at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:156)
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:376)
    at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:393)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
    at com.kms.katalon.core.webservice.common.HttpUtil.sendRequest(HttpUtil.java:146)
    at com.kms.katalon.core.webservice.common.BasicRequestor.send(BasicRequestor.java:58)
    at com.kms.katalon.core.webservice.helper.WebServiceCommonHelper.sendRequest(WebServiceCommonHelper.java:55)
    at com.kms.katalon.core.webservice.keyword.builtin.SendRequestKeyword$_sendRequest_closure1.doCall(SendRequestKeyword.groovy:40)
    at com.kms.katalon.core.webservice.keyword.builtin.SendRequestKeyword$_sendRequest_closure1.call(SendRequestKeyword.groovy)
    at com.kms.katalon.core.keyword.internal.KeywordMain.runKeyword(KeywordMain.groovy:75)
    at com.kms.katalon.core.webservice.keyword.builtin.SendRequestKeyword.sendRequest(SendRequestKeyword.groovy:38)
    at com.kms.katalon.core.webservice.keyword.builtin.SendRequestKeyword.execute(SendRequestKeyword.groovy:33)
    at com.kms.katalon.core.keyword.internal.KeywordExecutor.executeKeywordForPlatform(KeywordExecutor.groovy:74)
    at com.kms.katalon.core.webservice.keyword.WSBuiltInKeywords.sendRequest(WSBuiltInKeywords.groovy:41)
    at Script1721116693060.getResponseStatus(Script1721116693060.groovy:36)
    at Script1721116693060.run(Script1721116693060.groovy:21)
    ... 15 more
Caused by: java.net.ConnectException: Connection refused
    at org.apache.http.conn.socket.PlainConnectionSocketFactory.connectSocket(PlainConnectionSocketFactory.java:75)
    at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142)
    ... 34 more
)
Eception occured
2024-07-16 17:09:04.373 INFO  c.k.katalon.core.main.TestCaseExecutor   - END Test Cases/TestStuff2_abort_proxy
2024-07-16 17:09:04.377 INFO  c.k.katalon.core.main.TestCaseExecutor   - --------------------
2024-07-16 17:09:04.377 INFO  c.k.katalon.core.main.TestCaseExecutor   - START Test Cases/closeBrowser_stopProxy
2024-07-16 17:09:05.267 INFO  c.k.k.c.keyword.builtin.CommentKeyword   - wrote sample.har file
2024-07-16 17:09:07.390 INFO  c.k.katalon.core.main.TestCaseExecutor   - END Test Cases/closeBrowser_stopProxy
Exception in thread "Timer-0" java.lang.NullPointerException: Cannot invoke method abort() on null object
    at org.codehaus.groovy.runtime.NullObject.invokeMethod(NullObject.java:91)
    at org.codehaus.groovy.vmplugin.v8.IndyGuardsFiltersAndSignatures.invokeGroovyObjectInvoker(IndyGuardsFiltersAndSignatures.java:148)
    at org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:318)
    at Script1721116693060$_run_closure1.doCall(Script1721116693060.groovy:11)
    at Script1721116693060$_run_closure1.doCall(Script1721116693060.groovy)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:107)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
    at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:274)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1035)
    at groovy.lang.Closure.call(Closure.java:412)
    at groovy.lang.Closure.call(Closure.java:406)
    at org.codehaus.groovy.runtime.DefaultGroovyMethods$1.run(DefaultGroovyMethods.java:17443)
    at java.base/java.util.TimerThread.mainLoop(Timer.java:566)
    at java.base/java.util.TimerThread.run(Timer.java:516)
2024-07-16 17:09:07.669 INFO  com.kms.katalon.core.util.KeywordUtil    - Start generating HTML report folder at: /Users/kazuakiurayama/katalon-workspace/BrowserMobProxyInKatalonStudio/Reports/20240716_170849/TSx/20240716_170849...
2024-07-16 17:09:07.722 INFO  com.kms.katalon.core.util.KeywordUtil    - HTML report generated
2024-07-16 17:09:07.723 INFO  com.kms.katalon.core.util.KeywordUtil    - Start generating CSV report folder at: /Users/kazuakiurayama/katalon-workspace/BrowserMobProxyInKatalonStudio/Reports/20240716_170849/TSx/20240716_170849...
2024-07-16 17:09:07.752 INFO  com.kms.katalon.core.util.KeywordUtil    - CSV report generated
2024-07-16 17:09:07.811 INFO  c.k.katalon.core.main.TestSuiteExecutor  - --------------------
2024-07-16 17:09:07.812 INFO  c.k.katalon.core.main.TestSuiteExecutor  - END Test Suites/TSx
2024-07-16 17:09:07.812 INFO  c.k.katalon.core.main.TestSuiteExecutor  - ====================

I can see, the connection between the browser and HTTP server was forcibly disconnected.

Interesting.