appium / python-client

Python language bindings for Appium
Apache License 2.0
1.63k stars 556 forks source link

Need to change the orientation of app which is dependent on sensor #980

Open swalke12 opened 2 months ago

swalke12 commented 2 months ago

The problem

I have a mobile app which opens in portrait mode and later I need to switch to landscape mode. I have tried all possible solutions but the app does not turn to landscape mode but if I minimize the app , my emulator screen is changed to landscape. My app rotation is dependent on the sensor. How can I handle this using appium with python. I am using Appium-Python-Client 4.0.0.

Environment

Link to Appium Logs

[HTTP] <-- POST /wd/hub/session 200 8341 ms - 1017 [HTTP] [HTTP] --> GET /wd/hub/session/532110c9-f52f-408a-b2a7-b0a476e3b315/orientation [HTTP] {} [W3C (532110c9)] Driver proxy active, passing request on via HTTP proxy [debug] [WD Proxy] Matched '/wd/hub/session/532110c9-f52f-408a-b2a7-b0a476e3b315/orientation' to command name 'getOrientation' [debug] [WD Proxy] Proxying [GET /wd/hub/session/532110c9-f52f-408a-b2a7-b0a476e3b315/orientation] to [GET http://127.0.0.1:8203/wd/hub/session/cf21f8fe-7a33-44b8-94ad-1b8b62efc047/orientation] with no body [debug] [WD Proxy] Got response with status 200: {"sessionId":"cf21f8fe-7a33-44b8-94ad-1b8b62efc047","value":"PORTRAIT"} [WD Proxy] Replacing sessionId cf21f8fe-7a33-44b8-94ad-1b8b62efc047 with 532110c9-f52f-408a-b2a7-b0a476e3b315 [HTTP] <-- GET /wd/hub/session/532110c9-f52f-408a-b2a7-b0a476e3b315/orientation 200 1378 ms - 71 [HTTP] [HTTP] --> GET /wd/hub/session/532110c9-f52f-408a-b2a7-b0a476e3b315/orientation [HTTP] {} [W3C (532110c9)] Driver proxy active, passing request on via HTTP proxy [debug] [WD Proxy] Matched '/wd/hub/session/532110c9-f52f-408a-b2a7-b0a476e3b315/orientation' to command name 'getOrientation' [debug] [WD Proxy] Proxying [GET /wd/hub/session/532110c9-f52f-408a-b2a7-b0a476e3b315/orientation] to [GET http://127.0.0.1:8203/wd/hub/session/cf21f8fe-7a33-44b8-94ad-1b8b62efc047/orientation] with no body [debug] [WD Proxy] Got response with status 200: {"sessionId":"cf21f8fe-7a33-44b8-94ad-1b8b62efc047","value":"PORTRAIT"} [WD Proxy] Replacing sessionId cf21f8fe-7a33-44b8-94ad-1b8b62efc047 with 532110c9-f52f-408a-b2a7-b0a476e3b315 [HTTP] <-- GET /wd/hub/session/532110c9-f52f-408a-b2a7-b0a476e3b315/orientation 200 19 ms - 71 [HTTP] [HTTP] --> POST /wd/hub/session/532110c9-f52f-408a-b2a7-b0a476e3b315/orientation [HTTP] {"orientation":"LANDSCAPE"} [W3C (532110c9)] Driver proxy active, passing request on via HTTP proxy [debug] [WD Proxy] Matched '/wd/hub/session/532110c9-f52f-408a-b2a7-b0a476e3b315/orientation' to command name 'setOrientation' [debug] [WD Proxy] Proxying [POST /wd/hub/session/532110c9-f52f-408a-b2a7-b0a476e3b315/orientation] to [POST http://127.0.0.1:8203/wd/hub/session/cf21f8fe-7a33-44b8-94ad-1b8b62efc047/orientation] with body: {"orientation":"LANDSCAPE"} [WD Proxy] Got response with status 400: {"sessionId":"cf21f8fe-7a33-44b8-94ad-1b8b62efc047","value":{"error":"invalid element state","message":"Screen rotation cannot be changed to ROTATION_270 after 2000ms. Is it locked programmatically?","stacktrace":"io.appium.uiautomator2.common.exceptions.InvalidElementStateException: Screen rotation cannot be changed to ROTATION_270 after 2000ms. Is it locked programmatically?\n\tat io.appium.uiautomator2.model.internal.CustomUiDevice.setRotationSync(CustomUiDevice.java:184)\n\tat io.appium.uiautomator2.handler.SetOrientation.safeHandle(SetOrientation.java:41)\n\tat io.appium.uiautomator2.handler.request.SafeRequestHandler.handle(SafeRequestHandler.java:59)\n\tat io.appium.uiautomator2.server.AppiumServlet.handleRequest(AppiumServlet.java:266)\n\tat io.appium.uiautomator2.server.AppiumServlet.handleHttpRequest(AppiumServlet.java:260)\n\tat io.appium.uiautomator2.http.ServerHandler.channelRead(ServerHandler.java:68)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandle... [debug] [W3C] Matched W3C error code 'invalid element state' to InvalidElementStateError [HTTP] <-- POST /wd/hub/session/532110c9-f52f-408a-b2a7-b0a476e3b315/orientation 400 2068 ms - 3926

Code To reproduce issue

mykola-mokhnach commented 2 months ago
swalke12 commented 2 months ago

Hello ,

  1. I have moved to appium 2.5.2 , and again facing same issue when I execute d.orientation = "LANDSCAPE". I have attached the logs and also the sample program.

  2. Actually since the rotation change is dependent in the sensor , even if the location is locked to portrait , it I turn the device manually it changes the orientation to landscape within the app. I just want to handle it in my program.

logss.txt

mykola-mokhnach commented 2 months ago

there is no magic. We just call the standard UIAutomator API: https://github.com/appium/appium-uiautomator2-server/blob/a7190b06ffcf19f390a5f49b82880a4445fdcfdb/app/src/main/java/io/appium/uiautomator2/handler/SetOrientation.java#L31

If it does not work then it must fail for the original call as well, which means only Google can change this behaviour.

swalke12 commented 2 months ago

I am not sure why its not working. Is it because in the app the orientation is dependent on the sensor ?

mykola-mokhnach commented 2 months ago

it could be. I assume the original setRotationSync API performs OS-level mocking of orientation APIs, which makes client apps believe they are in landscape. Although by reading the data directly from the sensor this mock is not taken into consideration. Again, it is just my guess. I don't know how it works internally.

swalke12 commented 2 months ago

Can you please provide me sample python code for rotating the device or changing the orientation in appium 2 and appium-python-client 4.0.0

KazuCocoa commented 2 months ago

Genrally driver.orientation = 'landscape' https://github.com/appium/python-client/blob/9e63569b570d7a897264110a18c621c7a25f72ae/appium/webdriver/webdriver.py#L467 (affects https://github.com/appium/python-client/issues/980#issuecomment-2058963172) but I guess it did not work on your env as conversation the above.

You're saying "sensor", then if it could be via emulator, https://github.com/appium/appium-uiautomator2-driver?tab=readme-ov-file#mobile-sensorset might help. I don't use the method so much but you might be able to explore the usage and try it out