So , I am getting strange issue in my Framework.
After successfully completion of one test method , it does not shut down the app and start next .
If I run the methods individually it runs successfully .
**Exception which i am getting **
org.openqa.selenium.StaleElementReferenceException: android.support.test.uiautomator.StaleObjectException
at android.support.test.uiautomator.UiObject2.getAccessibilityNodeInfo(UiObject2.java:629)
at android.support.test.uiautomator.UiObject2.getVisibleBounds(UiObject2.java:210)
at android.support.test.uiautomator.UiObject2.getVisibleCenter(UiObject2.java:251)
at android.support.test.uiautomator.UiObject2.click(UiObject2.java:343)
at io.appium.uiautomator2.model.UiObject2Element.click(UiObject2Element.java:44)
at io.appium.uiautomator2.handler.Click.safeHandle(Click.java:40)
at io.appium.uiautomator2.handler.request.SafeRequestHandler.handle(SafeRequestHandler.java:56)
at io.appium.uiautomator2.server.AppiumServlet.handleRequest(AppiumServlet.java:202)
at io.appium.uiautomator2.server.AppiumServlet.handleHttpRequest(AppiumServlet.java:193)
at io.appium.uiautomator2.http.ServerHandler.channelRead(ServerHandler.java:44)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:366)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:352)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:345)
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:366)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:352)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:345)
at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:435)
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:293)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:267)
at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:250)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:366)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:352)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:345)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1294)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:366)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:352)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:911)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:131)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:611)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysPlain(NioEventLoop.java:514)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:468)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:438)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:140)
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144)
at java.lang.Thread.run(Thread.java:818)
public void setup() throws Exception {
Properties prop = new Properties();
InputStream input;
appiumService = AppiumDriverLocalService.buildDefaultService();
appiumService.start();
appiumServiceUrl=appiumService.getUrl().toString();
System.out.println("Appium server started at " +appiumServiceUrl);
So after every test it should start the server again ?
Yes , I sensed that , now i have changed the annotations to BeforSuite & AfterSuite. @BeforeSuite This is my complete BaseClass
public void setup() throws Exception {
Properties prop = new Properties();
InputStream input;
appiumService = AppiumDriverLocalService.buildDefaultService();
appiumService.start();
appiumServiceUrl=appiumService.getUrl().toString();
System.out.println("Appium server started at " +appiumServiceUrl);
//platform=prop.getProperty("platform");
try {
input = new FileInputStream("src/test/java/Utils/appiumSession.properties");
prop.load(input);
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("automationName", prop.getProperty("automationName"));
capabilities.setCapability("platformName", prop.getProperty("platformName"));
capabilities.setCapability("platformVersion", prop.getProperty("platformVersion"));
capabilities.setCapability("deviceName", prop.getProperty("deviceName"));
capabilities.setCapability("app", prop.getProperty("app"));
capabilities.setCapability("newCommandTimeout", "10");
/* Checking the platform */
platform = prop.getProperty("platform");
if (platform.equals("ANDROID")) {
driver = new AndroidDriver<>(new URL(appiumServiceUrl), capabilities);
} else if (platform.equals("IOS")) {
driver = new IOSDriver<>(new URL(appiumServiceUrl), capabilities);
driver.manage().timeouts().implicitlyWait(15,TimeUnit.SECONDS);
} else {
throw new Exception("Unable to read platform");
}
PageFactory.initElements(new AppiumFieldDecorator(driver, 5, TimeUnit.SECONDS), this);
} catch (IOException io) {
io.printStackTrace();
}
System.out.println("platform selected is " + driver);
}
@AfterSuite
public void tearDown () throws Exception {
driver.quit();
appiumService.stop();
}
Okay , I guess i was making mistake by not running the complete suite . Now I have added testng.xml. But now I am getting
java.lang.IllegalArgumentException: Can not set io.appium.java_client.MobileElement field PageObjects.LoginObjRep.user_id to org.openqa.selenium.remote.RemoteWebElement$$EnhancerByCGLIB$$d27c0df4
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81)
at java.lang.reflect.Field.set(Field.java:764)
at org.openqa.selenium.support.PageFactory.proxyFields(PageFactory.java:117)
at org.openqa.selenium.support.PageFactory.initElements(PageFactory.java:105)
at Pages.LoginPage.<init>(LoginPage.java:26)
Line 26 is where I am instantiating pagefactory objects
PageFactory.initElements(new AppiumFieldDecorator(driver),loginObjRep);
@igal_epshtein you testing web. Is it? Create your out clicker which repeat request after let say 100ms and up to 5 tries. I make such when had same problem while tests are executed too fast and element appeared but not in dom yet.
I’m using io.appium 6.1.0 with selenium-java 3.11.0 and guava 24.0-jre.
I’ve kept capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, “UiAutomator2”);
I’m using test class and calling individual page classes through the test class in the business functionality order - for loop ( lp.Login() -> functionality() [with different data]-> lop.logout() ) .
‘lp’ is the object of a page class.
The login, the functionality and then logout - each of them are methods of different page classes.
After a flow in a for loop, when the control comes to the login method again, I got: I got **android.support.test.uiautomator.StaleObjectException ** at android.support.test.uiautomator.UiObject2.getAccessibilityNodeInfo(UiObject2.java:629).
I am declaring all mobileelements in the page class and initializing them in the page class specific constructor using PageFactory.initElements(new AppiumFieldDecorator(driver), this);
Now, because the control is again trying to access the elements of the login() method page class, do I have to initialize the elements again ?
Here they say that :
A StaleObjectException exception is thrown when a UiObject2 is used after the underlying View has been destroyed. In this case, it is necessary to call findObject(BySelector) to obtain a new UiObject2 instance.