zebrunner / carina-webdriver

Apache License 2.0
7 stars 10 forks source link

don't do driver.quit call if driver wasn't started or was terminated #141

Open vdelendik opened 3 years ago

vdelendik commented 3 years ago

From time to time we observe during direct driver calls:

Expected to read a START_MAP but instead have: END. Last 0 characters read
session deleted because of page crash
Could not proxy command to the remote server. Original error: socket hang up

During the retry executor to confirm that driver died we can capture invalid session id exception.

It means that driver was terminated due to the different reasons and the most popular is timeout... As only we capture such kind of issue we have to raise exception asap and stop tests execution, moreover affected driver should be removed asap from the pool without driver.quit command!

SergeiZagriychuk commented 3 years ago

One more use case: Session [bcac2da6-2c3c-43d2-963f-ae08168be5d8] was terminated due to PROXY_REREGISTRATION

vdelendik commented 3 years ago

we have to define some algorithm to mark driver inside IDriverPool as staled/killed etc based on driverListener onException handler. As only we got any exception related to driver die we have to mark current driver in IDriverPool as staled. And during every operation with this driver don't execute. It has senes to raise exception asap

vdelendik commented 3 years ago

one of the negative case for new code:

15:09:28  2021-09-12 12:09:28 Messager [TestNG-test=Basic Tests-37-53] [ERROR] TEST [Basic Tests - testCartShareAndReturn] FAILED at [12:09:28 2021-09-12] - class com.sun.proxy.$Proxy19 cannot be cast to class org.openqa.selenium.remote.RemoteWebDriver (com.sun.proxy.$Proxy19 and org.openqa.selenium.remote.RemoteWebDriver are in unnamed module of loader 'app')
15:09:28  
15:09:28  com.qaprosoft.carina.core.foundation.webdriver.listener.DriverListener.onException(DriverListener.java:162)
15:09:28  jdk.internal.reflect.GeneratedMethodAccessor157.invoke(Unknown Source)
15:09:28  java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
15:09:28  java.base/java.lang.reflect.Method.invoke(Method.java:566)
15:09:28  org.openqa.selenium.support.events.EventFiringWebDriver.lambda$new$0(EventFiringWebDriver.java:84)
15:09:28  com.sun.proxy.$Proxy18.onException(Unknown Source)
15:09:28  org.openqa.selenium.support.events.EventFiringWebDriver$EventFiringWebElement.lambda$new$0(EventFiringWebDriver.java:406)
15:09:28  com.sun.proxy.$Proxy31.findElement(Unknown Source)
15:09:28  org.openqa.selenium.support.events.EventFiringWebDriver$EventFiringWebElement.findElement(EventFiringWebDriver.java:496)
15:09:28  jdk.internal.reflect.GeneratedMethodAccessor183.invoke(Unknown Source)
15:09:28  java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
15:09:28  java.base/java.lang.reflect.Method.invoke(Method.java:566)
15:09:28  org.openqa.selenium.support.pagefactory.internal.LocatingElementHandler.invoke(LocatingElementHandler.java:51)
15:09:28  com.sun.proxy.$Proxy30.findElement(Unknown Source)
15:09:28  com.qaprosoft.carina.core.foundation.webdriver.decorator.ExtendedWebElement.refindElement(ExtendedWebElement.java:389)
15:09:28  com.qaprosoft.carina.core.foundation.webdriver.decorator.ExtendedWebElement.doAction(ExtendedWebElement.java:1405)
15:09:28  com.qaprosoft.carina.core.foundation.webdriver.decorator.ExtendedWebElement.doAction(ExtendedWebElement.java:1363)
15:09:28  com.qaprosoft.carina.core.foundation.webdriver.decorator.ExtendedWebElement.click(ExtendedWebElement.java:520)
15:09:28  com.qaprosoft.carina.core.foundation.webdriver.decorator.ExtendedWebElement.click(ExtendedWebElement.java:506)
15:09:28  com.qaprosoft.carina.core.foundation.webdriver.decorator.ExtendedWebElement.click(ExtendedWebElement.java:497)
vdelendik commented 2 years ago

implementation should reuse benefits of the new CarinaCommandExecutor: https://github.com/zebrunner/carina/blob/5ade422293f906f7e5a01f91d92354f54b4d6ab1/carina-webdriver/src/main/java/com/qaprosoft/carina/core/foundation/webdriver/listener/CarinaCommandExecutor.java#L54

In scope of WebDriverException review actual error message, find all related to the dead driver/browser. During quick review I've found that initially we got driver connection refused but later it is converted to no such session etc. So in case of exact failure about died browser we have to:

  1. parse driver id from error message
  2. mark driver in IDriverPool as died using sessionid from log
  3. don't do any actions with driver, up to generating runtime exception in case of any command with it (part of logic before response = super.execute(command);???)
  4. during finish don't do one more quit operation on this browser (it seems like point 3 might solve this one automatically)

Point number 3 still TBD. It shouldn't affect neighbored tests

vdelendik commented 1 year ago

it should be assigned when carina-webdriver will be refactored or right after that

vdelendik commented 1 year ago

the same for no such session exception:

12:32:41  2023-08-18 10:32:41 Screenshot [TestNG-tests-14-33] [ERROR] Undefined error on capture screenshot detected!
12:32:41  org.openqa.selenium.NoSuchSessionException: Session does not exist[[[--udid 00008110-001005C11E78801E --name iPhone_13_mini --sessionId 2080b618-1842-42de-a344-2a03dc684fd7]]]
12:32:41  Build info: version: '4.7.0', revision: '0a5b49d16f'
12:32:41  System info: os.name: 'Linux', os.arch: 'amd64', os.version: '5.10.184-175.749.amzn2.x86_64', java.version: '17.0.7'
12:32:41  Driver info: io.appium.java_client.ios.IOSDriver
12:32:41  Command: [2080b618-1842-42de-a344-2a03dc684fd7, screenshot {}]
12:32:41  Capabilities {appium:app: https://mfp-solvd-com.s3.eu/..., appium:autoAcceptAlerts: false, appium:automationName: XCuiTest, appium:clearSystemFiles: false, appium:databaseEnabled: false, appium:deviceName: ANY, appium:deviceType: phone, appium:enableLog: true, appium:enableVideo: true, appium:fullReset: true, appium:javascriptEnabled: true, appium:language: en, appium:locale: en_US, appium:locationContextEnabled: false, appium:mjpegServerPort: 8101, appium:networkConnectionEnabled: false, appium:newCommandTimeout: 2000, appium:noReset: false, appium:platformVersion: 16.1, appium:preventWDAAttachments: true, appium:provider: mcloud, appium:simpleIsVisibleCheck: true, appium:takesScreenshot: true, appium:udid: 00008110-001005C11E78801E, appium:waitForQuiescence: false, appium:wdaLocalPort: 8100, appium:webDriverAgentUrl: http://localhost:8100/, appium:webStorageEnabled: false, platformName: IOS, server:CONFIG_UUID: f6de0b9b-afdd-451f-a8f1-7d2..., zebrunner:slotCapabilities: {adb_port: 7692, automationName: XCUITest, deviceName: iPhone_13_mini, deviceType: Phone, maxInstances: 1, platform: IOS, platformName: ios, platformVersion: 16.1, proxy_port: 7693, remoteURL: null, seleniumProtocol: WebDriver, server:CONFIG_UUID: f6de0b9b-afdd-451f-a8f1-7d2..., udid: 00008110-001005C11E78801E}}
12:32:41  Session ID: 2080b618-1842-42de-a344-2a03dc684fd7
12:32:41    at jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:?]
12:32:41    at jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) ~[?:?]
12:32:41    at jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) ~[?:?]
12:32:41    at java.lang.reflect.Constructor.newInstanceWithCaller(Unknown Source) ~[?:?]
12:32:41    at java.lang.reflect.Constructor.newInstance(Unknown Source) ~[?:?]
12:32:41    at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:200) ~[selenium-remote-driver-4.7.0.jar:?]
12:32:41    at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:133) ~[selenium-remote-driver-4.7.0.jar:?]
12:32:41    at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:53) ~[selenium-remote-driver-4.7.0.jar:?]
12:32:41    at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:184) ~[selenium-remote-driver-4.7.0.jar:?]
12:32:41    at io.appium.java_client.remote.AppiumCommandExecutor.execute(AppiumCommandExecutor.java:262) ~[java-client-8.3.0.jar:?]
12:32:41    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:541) ~[selenium-remote-driver-4.7.0.jar:?]
12:32:41    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:596) ~[selenium-remote-driver-4.7.0.jar:?]
12:32:41    at io.appium.java_client.AppiumDriver.execute(AppiumDriver.java:272) ~[java-client-8.3.0.jar:?]
12:32:41    at org.openqa.selenium.remote.RemoteWebDriver.getScreenshotAs$original$iv0cYGN2(RemoteWebDriver.java:331) ~[selenium-remote-driver-4.7.0.jar:?]
12:32:41    at org.openqa.selenium.remote.RemoteWebDriver.getScreenshotAs$original$iv0cYGN2$accessor$29DmtFiU(RemoteWebDriver.java) ~[selenium-remote-driver-4.7.0.jar:?]
12:32:41    at org.openqa.selenium.remote.RemoteWebDriver$auxiliary$o5fBrM6f.call(Unknown Source) ~[selenium-remote-driver-4.7.0.jar:?]
12:32:41    at com.zebrunner.agent.core.webdriver.PublicMethodInvocationInterceptor.onPublicMethodInvocation(PublicMethodInvocationInterceptor.java:18) ~[agent-core-1.9.6.jar:?]
12:32:41    at org.openqa.selenium.remote.RemoteWebDriver.getScreenshotAs(RemoteWebDriver.java) ~[selenium-remote-driver-4.7.0.jar:?]
12:32:41    at io.appium.java_client.AppiumDriver.getScreenshotAs(AppiumDriver.java:281) ~[java-client-8.3.0.jar:?]
12:32:41    at com.zebrunner.carina.webdriver.Screenshot.lambda$takeVisibleScreenshot$6(Screenshot.java:674) ~[carina-webdriver-1.1.6.P1-SNAPSHOT.jar:?]
12:32:41    at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:208) ~[selenium-support-4.7.0.jar:?]
12:32:41    at com.zebrunner.carina.webdriver.Screenshot.takeVisibleScreenshot(Screenshot.java:674) ~[carina-webdriver-1.1.6.P1-SNAPSHOT.jar:?]
12:32:41    at com.zebrunner.carina.webdriver.Screenshot.capture(Screenshot.java:386) ~[carina-webdriver-1.1.6.P1-SNAPSHOT.jar:?]
12:32:41    at com.zebrunner.carina.webdriver.Screenshot.lambda$capture$2(Screenshot.java:322) ~[carina-webdriver-1.1.6.P1-SNAPSHOT.jar:?]
12:32:41    at java.util.Optional.flatMap(Unknown Source) ~[?:?]
12:32:41    at com.zebrunner.carina.webdriver.Screenshot.capture(Screenshot.java:322) ~[carina-webdriver-1.1.6.P1-SNAPSHOT.jar:?]
12:32:41    at com.zebrunner.carina.webdriver.Screenshot.capture(Screenshot.java:291) ~[carina-webdriver-1.1.6.P1-SNAPSHOT.jar:?]
12:32:41    at com.zebrunner.carina.core.listeners.CarinaListener.takeScreenshot(CarinaListener.java:743) ~[carina-core-1.1.4.P1-SNAPSHOT.jar:?]
12:32:41    at com.zebrunner.carina.core.listeners.CarinaListener.onTestSkipped(CarinaListener.java:360) ~[carina-core-1.1.4.P1-SNAPSHOT.jar:?]
12:32:41    at com.nordstrom.automation.testng.ListenerChain.onTestSkipped(ListenerChain.java:411) ~[testng-foundation-2.0.1.jar:?]
12:32:41    at org.testng.internal.TestListenerHelper.runTestListeners(TestListenerHelper.java:90) ~[testng-7.7.1.jar:7.7.1]
12:32:41    at org.testng.internal.invokers.TestInvoker.runTestResultListener(TestInvoker.java:277) ~[testng-7.7.1.jar:7.7.1]
12:32:41    at org.testng.internal.invokers.TestInvoker.invokeMethod(TestInvoker.java:764) ~[testng-7.7.1.jar:7.7.1]
12:32:41    at org.testng.internal.invokers.TestInvoker.invokeTestMethod(TestInvoker.java:221) ~[testng-7.7.1.jar:7.7.1]
12:32:41    at org.testng.internal.invokers.MethodRunner.runInSequence(MethodRunner.java:50) ~[testng-7.7.1.jar:7.7.1]
12:32:41    at org.testng.internal.invokers.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:969) ~[testng-7.7.1.jar:7.7.1]
12:32:41    at org.testng.internal.invokers.TestInvoker.invokeTestMethods(TestInvoker.java:194) ~[testng-7.7.1.jar:7.7.1]
12:32:41    at org.testng.internal.invokers.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:148) ~[testng-7.7.1.jar:7.7.1]
12:32:41    at org.testng.internal.invokers.TestMethodWorker.run(TestMethodWorker.java:128) ~[testng-7.7.1.jar:7.7.1]
12:32:41    at java.util.ArrayList.forEach(Unknown Source) ~[?:?]
12:32:41    at org.testng.TestRunner.privateRun(TestRunner.java:829) ~[testng-7.7.1.jar:7.7.1]
12:32:41    at org.testng.TestRunner.run(TestRunner.java:602) ~[testng-7.7.1.jar:7.7.1]
12:32:41    at org.testng.SuiteRunner.runTest(SuiteRunner.java:437) ~[testng-7.7.1.jar:7.7.1]
12:32:41    at org.testng.SuiteRunner$SuiteWorker.run(SuiteRunner.java:475) ~[testng-7.7.1.jar:7.7.1]
12:32:41    at org.testng.internal.thread.ThreadUtil.lambda$execute$0(ThreadUtil.java:58) ~[testng-7.7.1.jar:7.7.1]
12:32:41    at java.util.concurrent.FutureTask.run(Unknown Source) [?:?]
12:32:41    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [?:?]
12:32:41    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [?:?]
12:32:41    at java.lang.Thread.run(Unknown Source) [?:?]
vdelendik commented 1 year ago

attaching example of the console log messages where due to the single problem we generate huge number of errors. Single fatal/critical should be at once if possible [Uploading session-not-found.log…]()