Skip to content

Commit

Permalink
feat: Expose API to Wait For UI Thread (#864)
Browse files Browse the repository at this point in the history
  • Loading branch information
sravanmedarapu committed Mar 26, 2023
1 parent 05f6d99 commit 18d71f6
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 0 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1121,6 +1121,12 @@ Lists all the previously registered [idling resources](https://developer.android

List of fully qualified class names of currently registered idling resources or an empty list if no resources have been registered yet.

### mobile: waitForUIThread

- Wait for the UI thread to become idle, in other words, wait for the APP to become idle(https://developer.android.com/reference/androidx/test/espresso/UiController#loopMainThreadUntilIdle()).
- Use case: On compose and native combination screens, it's possible for the Espresso API to block the UI thread, which can cause the app to freeze. To resolve this issue, it's recommended to explicitly call the `mobile:waitForUIThread` API, which can help to unfreeze the UI thread.


### mobile: unlock

Unlocks the device if it is locked. Noop if the device's screen is not locked.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.appium.espressoserver.lib.handlers

import androidx.test.espresso.UiController
import io.appium.espressoserver.lib.handlers.exceptions.AppiumException
import io.appium.espressoserver.lib.model.AppiumParams
import io.appium.espressoserver.lib.viewaction.UiControllerPerformer
import io.appium.espressoserver.lib.viewaction.UiControllerRunnable

class UIThreadSynchronizer : RequestHandler<AppiumParams, Void?> {
override fun handleInternal(params: AppiumParams): Void? {
val runnable = object : UiControllerRunnable<Void?> {
override fun run(uiController: UiController): Void? {
uiController.loopMainThreadUntilIdle()
return null
}
}

return UiControllerPerformer(runnable).run()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ internal class Router {
routeMap.addRoute(RouteDefinition(Method.POST, "/session/:sessionId/appium/execute_mobile/register_idling_resources", RegisterIdlingResources(), IdlingResourcesParams::class.java))
routeMap.addRoute(RouteDefinition(Method.POST, "/session/:sessionId/appium/execute_mobile/unregister_idling_resources", UnregisterIdlingResources(), IdlingResourcesParams::class.java))
routeMap.addRoute(RouteDefinition(Method.GET, "/session/:sessionId/appium/execute_mobile/list_idling_resources", ListIdlingResources(), AppiumParams::class.java))
routeMap.addRoute(RouteDefinition(Method.POST, "/session/:sessionId/appium/execute_mobile/ui_thread_sync", UIThreadSynchronizer(), AppiumParams::class.java))


// Not implemented
routeMap.addRoute(RouteDefinition(Method.POST, "/session/:sessionId/touch/flick", NotYetImplemented(), AppiumParams::class.java))
Expand Down
1 change: 1 addition & 0 deletions lib/commands/execute.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ extensions.executeMobile = async function executeMobile (mobileCommand, opts = {
registerIdlingResources: 'mobileRegisterIdlingResources',
unregisterIdlingResources: 'mobileUnregisterIdlingResources',
listIdlingResources: 'mobileListIdlingResources',
waitForUIThread: 'mobileWaitForUIThread',

unlock: 'mobileUnlock',

Expand Down
7 changes: 7 additions & 0 deletions lib/commands/idling-resources.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,12 @@ commands.mobileListIdlingResources = async function mobileListIdlingResources ()
return await this.espresso.jwproxy.command('/appium/execute_mobile/list_idling_resources', 'GET');
};

/**
* Wait for UI thread to be idle.
*/
commands.mobileWaitForUIThread = async function mobileWaitForUIThread () {
return await this.espresso.jwproxy.command('/appium/execute_mobile/ui_thread_sync', 'POST');
};

export { commands };
export default commands;

0 comments on commit 18d71f6

Please sign in to comment.