Skip to content

Commit

Permalink
Add wrappers for Android logcat broadcaster (#858)
Browse files Browse the repository at this point in the history
* Add wrappers for Android logcat broadcaster

* Address PR comments

* Remove unused arguments

* Tune execute args

* Add missing dependencies

* Add license headers

* Rewrite the stuff using functional approach

* Minimize the app to push log messages
  • Loading branch information
Mykola Mokhnach authored and SrinivasanTarget committed Apr 13, 2018
1 parent 8cf79ea commit 345676a
Show file tree
Hide file tree
Showing 11 changed files with 557 additions and 3 deletions.
5 changes: 4 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,10 @@ dependencies {
compile 'org.springframework:spring-context:5.0.3.RELEASE'
compile 'org.aspectj:aspectjweaver:1.8.13'
compile 'org.openpnp:opencv:3.2.0-1'

compile 'javax.websocket:javax.websocket-api:1.1'
compile 'org.glassfish.tyrus:tyrus-client:1.1'
compile 'org.glassfish.tyrus:tyrus-container-grizzly:1.1'

testCompile 'junit:junit:4.12'
testCompile 'org.hamcrest:hamcrest-all:1.3'
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public class AndroidDriver<T extends WebElement>
FindsByAndroidUIAutomator<T>, LocksDevice, HasAndroidSettings, HasDeviceDetails,
HasSupportedPerformanceDataType, AuthenticatesByFinger,
CanRecordScreen, SupportsSpecialEmulatorCommands,
SupportsNetworkStateManagement, HasAndroidClipboard {
SupportsNetworkStateManagement, ListensToLogcatMessages, HasAndroidClipboard {

private static final String ANDROID_PLATFORM = MobilePlatform.ANDROID;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/*
* 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.java_client.android;

import static io.appium.java_client.service.local.AppiumServiceBuilder.DEFAULT_APPIUM_PORT;
import static org.openqa.selenium.remote.DriverCommand.EXECUTE_SCRIPT;

import com.google.common.collect.ImmutableMap;

import io.appium.java_client.ExecutesMethod;
import io.appium.java_client.ws.StringWebSocketClient;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collections;
import java.util.function.Consumer;

public interface ListensToLogcatMessages extends ExecutesMethod {
StringWebSocketClient logcatClient = new StringWebSocketClient();

/**
* Start logcat messages broadcast via web socket.
* This method assumes that Appium server is running on localhost and
* is assigned to the default port (4723).
*/
default void startLogcatBroadcast() {
startLogcatBroadcast("localhost", DEFAULT_APPIUM_PORT);
}

/**
* Start logcat messages broadcast via web socket.
* This method assumes that Appium server is assigned to the default port (4723).
*
* @param host the name of the host where Appium server is running
*/
default void startLogcatBroadcast(String host) {
startLogcatBroadcast(host, DEFAULT_APPIUM_PORT);
}

/**
* Start logcat messages broadcast via web socket.
*
* @param host the name of the host where Appium server is running
* @param port the port of the host where Appium server is running
*/
default void startLogcatBroadcast(String host, int port) {
execute(EXECUTE_SCRIPT, ImmutableMap.of("script", "mobile: startLogsBroadcast",
"args", Collections.emptyList()));
final URI endpointUri;
try {
endpointUri = new URI(String.format("ws://%s:%s/ws/session/%s/appium/device/logcat",
host, port, ((RemoteWebDriver) this).getSessionId()));
} catch (URISyntaxException e) {
throw new IllegalArgumentException(e);
}
logcatClient.connect(endpointUri);
}

/**
* Adds a new log messages broadcasting handler.
* Several handlers might be assigned to a single server.
* Multiple calls to this method will cause such handler
* to be called multiple times.
*
* @param handler a function, which accepts a single argument, which is the actual log message
*/
default void addLogcatMessagesListener(Consumer<String> handler) {
logcatClient.addMessageHandler(handler);
}

/**
* Adds a new log broadcasting errors handler.
* Several handlers might be assigned to a single server.
* Multiple calls to this method will cause such handler
* to be called multiple times.
*
* @param handler a function, which accepts a single argument, which is the actual exception instance
*/
default void addLogcatErrorsListener(Consumer<Throwable> handler) {
logcatClient.addErrorHandler(handler);
}

/**
* Adds a new log broadcasting connection handler.
* Several handlers might be assigned to a single server.
* Multiple calls to this method will cause such handler
* to be called multiple times.
*
* @param handler a function, which is executed as soon as the client is successfully
* connected to the web socket
*/
default void addLogcatConnectionListener(Runnable handler) {
logcatClient.addConnectionHandler(handler);
}

/**
* Adds a new log broadcasting disconnection handler.
* Several handlers might be assigned to a single server.
* Multiple calls to this method will cause such handler
* to be called multiple times.
*
* @param handler a function, which is executed as soon as the client is successfully
* disconnected from the web socket
*/
default void addLogcatDisconnectionListener(Runnable handler) {
logcatClient.addDisconnectionHandler(handler);
}

/**
* Removes all existing logcat handlers.
*/
default void removeAllLogcatListeners() {
logcatClient.removeAllHandlers();
}

/**
* Stops logcat messages broadcast via web socket.
*/
default void stopLogcatBroadcast() {
execute(EXECUTE_SCRIPT, ImmutableMap.of("script", "mobile: stopLogsBroadcast",
"args", Collections.emptyList()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public final class AppiumServiceBuilder
File.separator + BUILD_FOLDER
+ File.separator + LIB_FOLDER
+ File.separator + MAIN_JS;
private static final int DEFAULT_APPIUM_PORT = 4723;
public static final int DEFAULT_APPIUM_PORT = 4723;
private static final String BASH = "bash";
private static final String CMD_EXE = "cmd.exe";
private static final String NODE = "node";
Expand Down
43 changes: 43 additions & 0 deletions src/main/java/io/appium/java_client/ws/CanHandleConnects.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* 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.java_client.ws;

import java.util.List;

public interface CanHandleConnects {

/**
* @return The list of web socket connection handlers.
*/
List<Runnable> getConnectionHandlers();

/**
* Register a new message handler.
*
* @param handler a callback function, which is going to be executed when web socket connection event arrives
*/
default void addConnectionHandler(Runnable handler) {
getConnectionHandlers().add(handler);
}

/**
* Removes existing web socket connection handlers.
*/
default void removeConnectionHandlers() {
getConnectionHandlers().clear();
}
}
43 changes: 43 additions & 0 deletions src/main/java/io/appium/java_client/ws/CanHandleDisconnects.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* 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.java_client.ws;

import java.util.List;

public interface CanHandleDisconnects {

/**
* @return The list of web socket disconnection handlers.
*/
List<Runnable> getDisconnectionHandlers();

/**
* Register a new web socket disconnect handler.
*
* @param handler a callback function, which is going to be executed when web socket disconnect event arrives
*/
default void addDisconnectionHandler(Runnable handler) {
getDisconnectionHandlers().add(handler);
}

/**
* Removes existing disconnection handlers.
*/
default void removeDisconnectionHandlers() {
getDisconnectionHandlers().clear();
}
}
44 changes: 44 additions & 0 deletions src/main/java/io/appium/java_client/ws/CanHandleErrors.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* 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.java_client.ws;

import java.util.List;
import java.util.function.Consumer;

public interface CanHandleErrors {

/**
* @return The list of web socket error handlers.
*/
List<Consumer<Throwable>> getErrorHandlers();

/**
* Register a new error handler.
*
* @param handler a callback function, which accepts the received exception instance as a parameter
*/
default void addErrorHandler(Consumer<Throwable> handler) {
getErrorHandlers().add(handler);
}

/**
* Removes existing error handlers.
*/
default void removeErrorHandlers() {
getErrorHandlers().clear();
}
}
44 changes: 44 additions & 0 deletions src/main/java/io/appium/java_client/ws/CanHandleMessages.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* 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.java_client.ws;

import java.util.List;
import java.util.function.Consumer;

public interface CanHandleMessages<T> {
/**
* @return The list of web socket message handlers.
*/
List<Consumer<T>> getMessageHandlers();

/**
* Register a new message handler.
*
* @param handler a callback function, which accepts the received message as a parameter
*/
default void addMessageHandler(Consumer<T> handler) {
getMessageHandlers().add(handler);
}

/**
* Removes existing message handlers.
*/
default void removeMessageHandlers() {
getMessageHandlers().clear();
}
}

Loading

0 comments on commit 345676a

Please sign in to comment.