-
Notifications
You must be signed in to change notification settings - Fork 0
James/threadcoderevert #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 16 commits
120198e
005509d
0febfa4
486a1de
a7c484c
d277642
0f47c2b
b558137
358595a
f50777f
b86518b
80e32eb
e10019c
70b921b
494eaa2
c80c9fa
857d75d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,22 +1,73 @@ | ||
| package com.moquality.android; | ||
|
|
||
| import android.graphics.Bitmap; | ||
| import android.os.Looper; | ||
| import android.util.Log; | ||
|
|
||
| import androidx.test.runner.screenshot.ScreenCapture; | ||
| import androidx.test.runner.screenshot.Screenshot; | ||
|
|
||
| import java.io.IOException; | ||
| import java.lang.reflect.InvocationTargetException; | ||
| import java.lang.reflect.Method; | ||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
||
| public class MoQuality { | ||
| public class MoQuality implements SocketIOHandlerThread.Callback { | ||
|
|
||
| public static String TAG = "MQ"; | ||
| private static String TAG = "MQ"; | ||
|
|
||
| private SocketIOHandlerThread mHandlerThread; | ||
|
|
||
| private ArrayList<Object> appTests = new ArrayList<>(); | ||
|
|
||
| public int log(String message) { | ||
| Log.i(TAG, message); | ||
| return 0; | ||
| } | ||
|
|
||
| public void register(Object test, String deviceId) { | ||
| this.appTests.add(test); | ||
|
|
||
| // launch Socket IO chat thread | ||
| if (Looper.myLooper() == null) { | ||
| Looper.prepare(); | ||
| } | ||
| mHandlerThread = new SocketIOHandlerThread(this, deviceId); | ||
| mHandlerThread.start(); | ||
| mHandlerThread.prepareHandler(); | ||
| } | ||
|
|
||
| public void unregister(Class test){ | ||
| for (Object testClass:appTests) { | ||
| if (testClass.getClass().getSimpleName().equalsIgnoreCase(test.getSimpleName())){ | ||
| appTests.remove(testClass); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| public void shutdown() { | ||
| if(mHandlerThread != null){ | ||
| mHandlerThread.quit(); | ||
| mHandlerThread.interrupt(); | ||
| } | ||
| } | ||
|
|
||
| public void runSocketIOTest() { | ||
| mHandlerThread.queueTask(TestConstants.SOCKET_IO_START); | ||
| try { | ||
| long threadStartTime = System.currentTimeMillis(); | ||
| long executionTimeInMillis = 0; | ||
| while (mHandlerThread.isThreadAlive()) { | ||
| executionTimeInMillis = System.currentTimeMillis() - threadStartTime; | ||
| } | ||
|
|
||
| Log.i("SOCKET_IO THREAD", "Execution time = " + executionTimeInMillis/1000 + " seconds"); | ||
| } catch (Exception e) { | ||
| Log.d("SOCKET IO", "Test interrupted"); | ||
| } | ||
| } | ||
|
|
||
| public void takeScreenshot(String name) throws IOException { | ||
| log("Saving screenshot "+name); | ||
| ScreenCapture capture = Screenshot.capture(); | ||
|
|
@@ -29,5 +80,90 @@ public void takeScreenshot(String name) throws IOException { | |
| throw e; | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| public void onSocketTaskCompleted(int taskId) { | ||
| switch (taskId){ | ||
| case TestConstants.SOCKET_IO_MSG_RECEIVED: | ||
| Log.i(TAG, "Message received in UI"); | ||
| break; | ||
| case TestConstants.SOCKET_IO_DISCONNECTED: | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| public void onSocketEventReceived(String eventName, String method, List<Class> classArgs, List<String> stringArgs) { | ||
| switch (eventName){ | ||
| case TestConstants.SOCKET_EVENT_CALL: | ||
| Log.i(TAG, "CALL command received for this device."); | ||
| callAppTestMethod(method, classArgs, stringArgs); | ||
| break; | ||
| case TestConstants.SOCKET_EVENT_STATUS: | ||
| Log.i(TAG, "STATUS command received for this device."); | ||
| break; | ||
| case TestConstants.SOCKET_EVENT_RETURN: | ||
| Log.i(TAG, "RETURN command received for this device."); | ||
| } | ||
| } | ||
|
|
||
| private void setMode(String mode) { | ||
| switch (mode) { | ||
| case "reflect": | ||
| mHandlerThread.queueTask(TestConstants.REFLECT_MODE); | ||
|
|
||
| break; | ||
| case "quit": | ||
| this.mHandlerThread.quit(); | ||
|
|
||
| break; | ||
| default: | ||
| Log.i(TAG, "Unhandled mode " + mode); | ||
| //mHandlerThread.queueTask(TestConstants.DEFAULT_MODE); | ||
| } | ||
| } | ||
|
|
||
| private void callAppTestMethod(String method, List<Class> classArgs, List<String> stringArgs){ | ||
| if (appTests!=null) { | ||
|
|
||
| if (stringArgs!=null && stringArgs.size()>0) { | ||
| Log.i(TAG, "******* METHOD = " + method + " ARGS = " + stringArgs.get(0)); | ||
| } else { | ||
| Log.i(TAG, "******* METHOD = " + method); | ||
| } | ||
| if (method.equalsIgnoreCase("setMode")){ | ||
| if (stringArgs!=null) { | ||
| setMode(stringArgs.get(0)); | ||
| } | ||
| } else { | ||
| for (Object testClass:appTests) { | ||
| try { | ||
| Method m = testClass.getClass().getMethod(method, classArgs.toArray(new Class[0])); | ||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So, we're searching for a method in all the Test Classes and selecting the first test method? What if two methods in 2 classes have the same name? Perhaps it's best to have 2 methods -- one where you can specify and the other where it does a lookup like this... |
||
| try { | ||
| Log.i(TAG, testClass.getClass().getSimpleName() + " - method called = " + m.toString()); | ||
| String data = ""; | ||
| if (stringArgs != null && stringArgs.size() > 0) { | ||
| data = m.invoke(testClass, stringArgs.toArray(new String[0])).toString(); | ||
| } else { | ||
| data = m.invoke(testClass).toString(); | ||
| } | ||
| Log.i(TAG, "return " + data); | ||
| } catch (NullPointerException e) { | ||
| Log.i(TAG, "Error returning data from method invoke()"); | ||
| } catch (IllegalAccessException e) { | ||
| Log.i(TAG, method + " invoke error - Illegal Access Exception"); | ||
| } catch (InvocationTargetException e) { | ||
| Log.i(TAG, method + " invoke error - Invocation Target Exception"); | ||
| } | ||
| } catch (NoSuchMethodException e) { | ||
| Log.i(TAG, "Method (" + method + ") not found in app test class " + testClass.getClass().getSimpleName()); | ||
| } catch (NullPointerException e){ | ||
| Log.i(TAG, "Null pointer exception on class constructor."); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how does the test get a deviceId? I am assuming in Espresso code, the client will call
MoQuality.register(class, "device1")If this is the case, then they are hardcoding the deviceId in the test, which means they would have to generate a new APK for
device2. Is that right? Ideally we would want this to be dynamically assigned to the test via a command line argument or something. In Android, when running the test from command line, clients can supply key value pairs to am instrument e.g.,-e deviceId device1.https://developer.android.com/studio/test/command-line#AMOptionsSyntax
These can be fetched from within the code using the
InstrumentationRegistry.getArguments()https://developer.android.com/reference/android/support/test/InstrumentationRegistry
https://github.com/android/android-test/blob/master/runner/monitor/java/androidx/test/InstrumentationRegistry.java