I’m having a problem with screen recording on real Android TV devices. I’m using Python + Behave, so I’m using the before_scenario and after_scenario hooks to start and stop recording:
That is the code, with minimal changes since I joined the project. My previous colleague, who I am replacing, wrote this code, and from a video he has from April as a knowledge transfer, at that time the video was created and attached correctly in allure and jira issue.
Now, the file is created (and attached in allure report and jira issue) but it is empty and with 0 bytes, which in addition, jira identifies as an empty attachment and although it returns a 200 response (and as I said, it attaches the file in the issue), I get an error that stops the execution.
This error is not my main problem (I only mention it because it is annoying, since it prevents the last command, which is the jira issue state transition, from being executed).
What worries me and I can not solve is that apparently it is not recording anything and creates an empty mp4 file and I do not understand why 6 months ago it worked and now it does not.
The environment I’m using is as follows (I do not know which one was used by my former colleague):
Appium: 2.1.3 and I have upgraded to the latest version → 2.2.1. Does not work with either.
Appium_Python_Client: 3.0.0 and I have upgraded to the latest version → 3.1.0. Does not work with either.
Selenium: 4.12.0 and I have upgraded to the latest version → 4.14.0. Does not work with either.
2023-10-26 07:49:27:265 [HTTP] ← POST /wd/hub/session/b321b20f-22aa-4cad-b625-b256cc98196f/appium/start_recording_screen 200 745 ms - 12
Here the screen recording is started. Then a new session is requested without ending the previous one and a request to stop the recording from that second session (pay attention to the session id in the URL path):
2023-10-26 07:49:50:044 [HTTP] → POST /wd/hub/session/dd700fd3-d127-4db3-8cdd-26e196faf079/appium/stop_recording_screen
Of course this won’t work. Also, you can manually verify if the device under test is capable of recording any videos by running adb shell screenrecord
You are absoluty right. I didn’t notice that in the log, and as soon as you remarked it, I knew what was the problem.
Indeed, two sessions were being created, and the first one, which is the one that started the recording, was not closing, and the one that tried to close it at the end of the scenario was the second one.
Once I fixed this, the recording works perfectly.
This was happening because when I updated selenium, I had to change the way in which I passed the capabilities to the driver and in top of that, they also removed the reset() method so I solved this problem with this workaround:
But I didn’t realice that with this, I was creating another session without even closing the first one. I guess I could stop the recording and close the session here before I create the new one. Probably there is a better way to do this, but I don’t know how.
Anyway, thank you so much for you help.
Kind regards.
My problem here is that for some scenarios I need to reset the application, but for the vast majority of them, I don’t need to. This had easy solution: I have the noReset capability set to True and then, in the scenarios I need to reset, I use a behave step with the reset() method implemented.
But since this method was deprecated in the latest versions of Selenium and I start the capabilities in the before_all hook, the only way I found to do this was, instead of using the reset() method, to change the reset capability value to False when I use that behave step, which forces me to create a new session with the updated capabilities.
I looked for a solution for this, but found nothing, and the only thing I could come up with was this.
I don’t know those APIs that could allow me to reset the app. If you know them, please, could you tell me which ones?
Yes, that’s right, we are using the UIA2 driver. The problem is that when I try to call the clear method with the driver, nothing appears. Other methods that are on that page you put, like install_app or background_app, do appear and I can use them, but clear_app or something related does not come up in my case. In fact, if I go to applications.py module, which is in appium/webdriver/extensions in my case, there is nothing about a clear or reset method.
I don’t know if it’s because it’s python, and it doesn’t exist in python. Maybe in Java exists, I don’t know.
Actually, I think I tried this before, the clean_app method, but I couldn’t find it either.
I found this thread where the removal of some methods, including resetApp() is discussed: https://github.com/appium/appium/issues/15807
Speaking on this subject, the first comment says: […] In their place, users should rely on standard Appium session management (new session + caps, delete session)[…]
Which is more and less, I think, what I did.
It also recommends the clearApp() method but, as I said, it doesn’t exist for me.
I read the thread quickly, so maybe I missed something else (I will read it more carefully), but it seems that it’s pretty much this: or use clearApp(), or mess with sessions or remove/install app, which right now it’s not an option.
@Aleksei I tried your solution and it worked like a charm. Also superfast. The only thing is that when I start the Appium server, I have to set “–allow-insecure=adb_shell” in the command, because if not, I get a security error.
@mykola-mokhnach What I mean by does not exist is that the IDE does not show me the option. For example, I type driver. and I get a bunch of methods that I can use but none that contain clear or clean or anything related. And if I look in the modules or classes from which these methods come from in the appium/selenium environment, I can’t find anything either.
Anyway, I have also tried your solution but I don’t know if I am doing something wrong because it gives me an error all the time.
The error is this one:
Traceback (most recent call last):
File “/Users/user/WSP/auto-android-stb/.venv/lib/python3.11/site-packages/behave/model.py”, line 1329, in run
match.run(runner.context)
File “/Users/user/WSP/auto-android-stb/.venv/lib/python3.11/site-packages/behave/matchers.py”, line 98, in run
self.func(context, *args, **kwargs)
File “src/test/features/steps/app_steps.py”, line 29, in step_impl
driver.execute_script(“mobile: clearApp”, {“component”: “app”})
File “/Users/user/WSP/auto-android-stb/.venv/lib/python3.11/site-packages/selenium/webdriver/remote/webdriver.py”, line 404, in execute_script
return self.execute(command, {“script”: script, “args”: converted_args})[“value”]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/Users/user/WSP/auto-android-stb/.venv/lib/python3.11/site-packages/selenium/webdriver/remote/webdriver.py”, line 344, in execute
self.error_handler.check_response(response)
File “/Users/user/WSP/auto-android-stb/.venv/lib/python3.11/site-packages/appium/webdriver/errorhandler.py”, line 125, in check_response
raise exception_class(msg=message, stacktrace=format_stacktrace(stacktrace))
selenium.common.exceptions.InvalidArgumentException: Message: ‘appId’ argument must be provided
Stacktrace:
InvalidArgumentError: ‘appId’ argument must be provided
at requireArgs (/Users/user/.appium/node_modules/appium-uiautomator2-driver/node_modules/appium-android-driver/lib/utils.js:16:13)
at AndroidUiautomator2Driver.mobileClearApp (/Users/user/.appium/node_modules/appium-uiautomator2-driver/node_modules/appium-android-driver/lib/commands/app-management.js:165:32)
at AndroidUiautomator2Driver.executeMobile (/Users/user/.appium/node_modules/appium-uiautomator2-driver/lib/commands/general.js:177:84)
at AndroidUiautomator2Driver.execute (/Users/user/.appium/node_modules/appium-uiautomator2-driver/lib/commands/general.js:139:27)
at commandExecutor (/opt/homebrew/lib/node_modules/appium/node_modules/@appium/base-driver/lib/basedriver/driver.ts:107:18)
at /opt/homebrew/lib/node_modules/appium/node_modules/async-lock/lib/index.js:171:12
at AsyncLock._promiseTry (/opt/homebrew/lib/node_modules/appium/node_modules/async-lock/lib/index.js:304:31)
at exec (/opt/homebrew/lib/node_modules/appium/node_modules/async-lock/lib/index.js:170:9)
at AsyncLock.acquire (/opt/homebrew/lib/node_modules/appium/node_modules/async-lock/lib/index.js:187:3)
at AndroidUiautomator2Driver.executeCommand (/opt/homebrew/lib/node_modules/appium/node_modules/@appium/base-driver/lib/basedriver/driver.ts:123:39)
at processTicksAndRejections (node:internal/process/task_queues:95:5)
at defaultBehavior (/opt/homebrew/lib/node_modules/appium/lib/appium.js:722:14)
at AppiumDriver.executeWrappedCommand (/opt/homebrew/lib/node_modules/appium/lib/appium.js:828:16)
at AppiumDriver.executeCommand (/opt/homebrew/lib/node_modules/appium/lib/appium.js:734:17)
at asyncHandler (/opt/homebrew/lib/node_modules/appium/node_modules/@appium/base-driver/lib/protocol/protocol.js:393:19)
I don’t know if I understood properly the way I should build the method. I have something like this:
I tried a bunch of combinations for the value of the component but none has worked. I also tried removing the commas at the end.
I really would like this to work because for Android I’ve got the adb command, but for iOS I will need a solution, and this seems a good one.
Ufff that’s a drag for me right now. I would prefer to have it as I have it so far, which is to quit the session started at the beginning, change the noReset capability and start a new session again.