detox 20.13.1-smoke.0 → 20.13.2-smoke.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. package/Detox-android/com/wix/detox/{20.13.1-smoke.0/detox-20.13.1-smoke.0-javadoc.jar → 20.13.2-smoke.0/detox-20.13.2-smoke.0-javadoc.jar} +0 -0
  2. package/Detox-android/com/wix/detox/20.13.2-smoke.0/detox-20.13.2-smoke.0-javadoc.jar.md5 +1 -0
  3. package/Detox-android/com/wix/detox/20.13.2-smoke.0/detox-20.13.2-smoke.0-javadoc.jar.sha1 +1 -0
  4. package/Detox-android/com/wix/detox/20.13.2-smoke.0/detox-20.13.2-smoke.0-javadoc.jar.sha256 +1 -0
  5. package/Detox-android/com/wix/detox/20.13.2-smoke.0/detox-20.13.2-smoke.0-javadoc.jar.sha512 +1 -0
  6. package/Detox-android/com/wix/detox/{20.13.1-smoke.0/detox-20.13.1-smoke.0-sources.jar → 20.13.2-smoke.0/detox-20.13.2-smoke.0-sources.jar} +0 -0
  7. package/Detox-android/com/wix/detox/20.13.2-smoke.0/detox-20.13.2-smoke.0-sources.jar.md5 +1 -0
  8. package/Detox-android/com/wix/detox/20.13.2-smoke.0/detox-20.13.2-smoke.0-sources.jar.sha1 +1 -0
  9. package/Detox-android/com/wix/detox/20.13.2-smoke.0/detox-20.13.2-smoke.0-sources.jar.sha256 +1 -0
  10. package/Detox-android/com/wix/detox/20.13.2-smoke.0/detox-20.13.2-smoke.0-sources.jar.sha512 +1 -0
  11. package/Detox-android/com/wix/detox/20.13.2-smoke.0/detox-20.13.2-smoke.0.aar +0 -0
  12. package/Detox-android/com/wix/detox/20.13.2-smoke.0/detox-20.13.2-smoke.0.aar.md5 +1 -0
  13. package/Detox-android/com/wix/detox/20.13.2-smoke.0/detox-20.13.2-smoke.0.aar.sha1 +1 -0
  14. package/Detox-android/com/wix/detox/20.13.2-smoke.0/detox-20.13.2-smoke.0.aar.sha256 +1 -0
  15. package/Detox-android/com/wix/detox/20.13.2-smoke.0/detox-20.13.2-smoke.0.aar.sha512 +1 -0
  16. package/Detox-android/com/wix/detox/{20.13.1-smoke.0/detox-20.13.1-smoke.0.pom → 20.13.2-smoke.0/detox-20.13.2-smoke.0.pom} +1 -1
  17. package/Detox-android/com/wix/detox/20.13.2-smoke.0/detox-20.13.2-smoke.0.pom.md5 +1 -0
  18. package/Detox-android/com/wix/detox/20.13.2-smoke.0/detox-20.13.2-smoke.0.pom.sha1 +1 -0
  19. package/Detox-android/com/wix/detox/20.13.2-smoke.0/detox-20.13.2-smoke.0.pom.sha256 +1 -0
  20. package/Detox-android/com/wix/detox/20.13.2-smoke.0/detox-20.13.2-smoke.0.pom.sha512 +1 -0
  21. package/Detox-android/com/wix/detox/maven-metadata.xml +4 -4
  22. package/Detox-android/com/wix/detox/maven-metadata.xml.md5 +1 -1
  23. package/Detox-android/com/wix/detox/maven-metadata.xml.sha1 +1 -1
  24. package/Detox-android/com/wix/detox/maven-metadata.xml.sha256 +1 -1
  25. package/Detox-android/com/wix/detox/maven-metadata.xml.sha512 +1 -1
  26. package/Detox-ios-src.tbz +0 -0
  27. package/Detox-ios.tbz +0 -0
  28. package/android/detox/src/full/java/com/wix/detox/espresso/web/WebElement.java +4 -4
  29. package/android/detox/src/full/java/com/wix/invoke/types/Invocation.java +2 -2
  30. package/android/detox/src/main/java/com/wix/detox/espresso/action/common/MotionEvents.kt +31 -2
  31. package/android/detox/src/testFull/java/com/wix/invoke/JsonParserTest.java +23 -7
  32. package/android/detox/src/testFull/resources/targetInvocationEspressoWebDetoxScript.json +47 -0
  33. package/index.d.ts +15 -12
  34. package/package.json +2 -2
  35. package/src/android/core/WebElement.js +23 -5
  36. package/src/android/espressoapi/web/WebElement.js +1 -4
  37. package/src/utils/assertIsFunction.js +35 -0
  38. package/src/utils/isArrowFunction.js +24 -0
  39. package/Detox-android/com/wix/detox/20.13.1-smoke.0/detox-20.13.1-smoke.0-javadoc.jar.md5 +0 -1
  40. package/Detox-android/com/wix/detox/20.13.1-smoke.0/detox-20.13.1-smoke.0-javadoc.jar.sha1 +0 -1
  41. package/Detox-android/com/wix/detox/20.13.1-smoke.0/detox-20.13.1-smoke.0-javadoc.jar.sha256 +0 -1
  42. package/Detox-android/com/wix/detox/20.13.1-smoke.0/detox-20.13.1-smoke.0-javadoc.jar.sha512 +0 -1
  43. package/Detox-android/com/wix/detox/20.13.1-smoke.0/detox-20.13.1-smoke.0-sources.jar.md5 +0 -1
  44. package/Detox-android/com/wix/detox/20.13.1-smoke.0/detox-20.13.1-smoke.0-sources.jar.sha1 +0 -1
  45. package/Detox-android/com/wix/detox/20.13.1-smoke.0/detox-20.13.1-smoke.0-sources.jar.sha256 +0 -1
  46. package/Detox-android/com/wix/detox/20.13.1-smoke.0/detox-20.13.1-smoke.0-sources.jar.sha512 +0 -1
  47. package/Detox-android/com/wix/detox/20.13.1-smoke.0/detox-20.13.1-smoke.0.aar +0 -0
  48. package/Detox-android/com/wix/detox/20.13.1-smoke.0/detox-20.13.1-smoke.0.aar.md5 +0 -1
  49. package/Detox-android/com/wix/detox/20.13.1-smoke.0/detox-20.13.1-smoke.0.aar.sha1 +0 -1
  50. package/Detox-android/com/wix/detox/20.13.1-smoke.0/detox-20.13.1-smoke.0.aar.sha256 +0 -1
  51. package/Detox-android/com/wix/detox/20.13.1-smoke.0/detox-20.13.1-smoke.0.aar.sha512 +0 -1
  52. package/Detox-android/com/wix/detox/20.13.1-smoke.0/detox-20.13.1-smoke.0.pom.md5 +0 -1
  53. package/Detox-android/com/wix/detox/20.13.1-smoke.0/detox-20.13.1-smoke.0.pom.sha1 +0 -1
  54. package/Detox-android/com/wix/detox/20.13.1-smoke.0/detox-20.13.1-smoke.0.pom.sha256 +0 -1
  55. package/Detox-android/com/wix/detox/20.13.1-smoke.0/detox-20.13.1-smoke.0.pom.sha512 +0 -1
@@ -0,0 +1 @@
1
+ aed3144cf5a80b4046c73d970e49115e
@@ -0,0 +1 @@
1
+ f4f85a773de8b58654465e6f7db1b399696a4a2b
@@ -0,0 +1 @@
1
+ fe64614559c38fb8e472eb60c7c16b0b86a61dea56f6f68c7420b5684b7a0d9b
@@ -0,0 +1 @@
1
+ 2b428f525b3e17beec96d3e68ed0fcd422f1899e76ca9ffd0e47bb0e61771d3c2b592cdfd8a16e98d8a8bc28fe74617aab8b3525a89d290bef08d5c0a4cdff85
@@ -0,0 +1 @@
1
+ a4f08802e3b662a41e772c9bf6e2311c
@@ -0,0 +1 @@
1
+ 9d9556a5ed54cee8a37d6d2588789b8f783f4392
@@ -0,0 +1 @@
1
+ 9190d8d16a419d503cf6e962f8c70445192bf682bee9fd2bc8852acb9e2b8a00
@@ -0,0 +1 @@
1
+ 9a4ecc2d59aace1ba9f77075f0988f8040c1e5dc81d2d4202e8a82b8610a3532049a62c4e4cde1fc8cabfed55583edcdd1c966a3f0eab313ec6b941906ee0d7d
@@ -0,0 +1 @@
1
+ 5037d89ac5d98e47d69d63b8731e7e3a
@@ -0,0 +1 @@
1
+ b4a0f9db575d92cb2da51c617e0ff531330cc2c6
@@ -0,0 +1 @@
1
+ 1fa253115965db1c97bc6c8b0c1ab0dff9ac9f8714e063dc972332cc6798b63a
@@ -0,0 +1 @@
1
+ 8174914ad6abe68c79f4812a32d292e80d922239045a30401bc39f43801f3cd2ea2807786248ffb58e84dfcdb8eddc00c7f606a874eb216def9350d325442af3
@@ -3,7 +3,7 @@
3
3
  <modelVersion>4.0.0</modelVersion>
4
4
  <groupId>com.wix</groupId>
5
5
  <artifactId>detox</artifactId>
6
- <version>20.13.1-smoke.0</version>
6
+ <version>20.13.2-smoke.0</version>
7
7
  <packaging>aar</packaging>
8
8
  <name>Detox</name>
9
9
  <description>Gray box end-to-end testing and automation library for mobile apps</description>
@@ -0,0 +1 @@
1
+ 46ebf87087df0576ab48ed182fcc09a9
@@ -0,0 +1 @@
1
+ 5f28dca347e18a8f21351687806b3c974df1b4ce
@@ -0,0 +1 @@
1
+ aad69b1b0b844e8ed8cf1fede3ffdcac22e1a06282540b85cdc4f7ec3be9db45
@@ -0,0 +1 @@
1
+ 044ae15c07145dff68b1b203ce9ff808aa8763717fcc622fd500bf24be68a196426efd4ae17813cd6ae0b4333112e8db40c302f0019d65b4452f506586ad25c0
@@ -3,11 +3,11 @@
3
3
  <groupId>com.wix</groupId>
4
4
  <artifactId>detox</artifactId>
5
5
  <versioning>
6
- <latest>20.13.1-smoke.0</latest>
7
- <release>20.13.1-smoke.0</release>
6
+ <latest>20.13.2-smoke.0</latest>
7
+ <release>20.13.2-smoke.0</release>
8
8
  <versions>
9
- <version>20.13.1-smoke.0</version>
9
+ <version>20.13.2-smoke.0</version>
10
10
  </versions>
11
- <lastUpdated>20231013072538</lastUpdated>
11
+ <lastUpdated>20231018131334</lastUpdated>
12
12
  </versioning>
13
13
  </metadata>
@@ -1 +1 @@
1
- d2a9c4ea918b24f4cf98e1194d3fafd2
1
+ d8ebcc249215377bd9b442106dfba2b4
@@ -1 +1 @@
1
- 90e450b35693d5015c5ac0dc212700fbe1780c10
1
+ b14128e6589b7f493c0a2f9a54b9cb8531603319
@@ -1 +1 @@
1
- ee38fbc385e4c227685a4fc0290cda3a77f6056cc27e914db9b055c9ac14c66d
1
+ 7c0b53a7a0d4e737aecc9ab369b2780cda29bfbc07e33fad2a138cd6a5e55d5c
@@ -1 +1 @@
1
- 4fca6bd96454869278ee77d1e116e4f929a898943b979896ff04a7e618e52a5122278890227543e2b00e3968f997eec0a3cd6b7a91fe64b0a4f1e0ba36c0ffdb
1
+ 8463f9543be4cb82d2a3ff43c0525b932a59fda20c731bbf4aa35e7180cef54b2f8070580e5dbdd7ac2552934727c5a02cc360138c3b08a539c052ecbd9ca18e
package/Detox-ios-src.tbz CHANGED
Binary file
package/Detox-ios.tbz CHANGED
Binary file
@@ -62,12 +62,12 @@ public class WebElement {
62
62
  return getWebViewInteraction().withElement(get()).perform(DriverAtoms.getText()).get();
63
63
  }
64
64
 
65
- public Evaluation runScript(String script) {
66
- return getWebViewInteraction().withElement(get()).perform(new SimpleAtom(script)).get();
65
+ public Object runScript(String script) {
66
+ return getWebViewInteraction().withElement(get()).perform(new SimpleAtom(script)).get().getValue();
67
67
  }
68
68
 
69
- public Evaluation runScriptWithArgs(String script, final ArrayList<Object> args) {
70
- return getWebViewInteraction().withElement(get()).perform(Atoms.scriptWithArgs(script, args)).get();
69
+ public Object runScriptWithArgs(String script, final ArrayList<Object> args) {
70
+ return getWebViewInteraction().withElement(get()).perform(Atoms.scriptWithArgs(script, args)).get().getValue();
71
71
  }
72
72
 
73
73
  public String getCurrentUrl() {
@@ -68,9 +68,9 @@ public class Invocation {
68
68
  argument = args.get(i);
69
69
  } else if(args.get(i).getClass() == JSONArray.class) {
70
70
  JSONArray jsonArray = (JSONArray) args.get(i);
71
- List<String> list = new ArrayList<>();
71
+ List<Object> list = new ArrayList<>();
72
72
  for (int j = 0; j < jsonArray.length(); j++) {
73
- list.add(jsonArray.getString(j));
73
+ list.add(jsonArray.get(j));
74
74
  }
75
75
  argument = list;
76
76
  } else {
@@ -9,8 +9,37 @@ import androidx.test.espresso.action.MotionEvents
9
9
  private val PRECISION = floatArrayOf(16f, 16f)
10
10
 
11
11
  class MotionEvents {
12
- fun obtainMoveEvent(downEvent: MotionEvent, eventTime: Long, x: Float, y: Float): MotionEvent
13
- = MotionEvents.obtainMovement(downEvent.downTime, eventTime, floatArrayOf(x, y))!!
12
+ fun obtainMoveEvent(downEvent: MotionEvent, eventTime: Long, x: Float, y: Float): MotionEvent {
13
+ val pointerProperties = MotionEvent.PointerProperties().apply {
14
+ clear()
15
+ id = 0
16
+ toolType = MotionEvent.TOOL_TYPE_UNKNOWN
17
+ }
18
+ val pointerCoords = MotionEvent.PointerCoords().apply {
19
+ clear()
20
+ this.x = x
21
+ this.y = y
22
+ this.pressure = 0f
23
+ this.size = 1f
24
+ }
25
+
26
+ return MotionEvent.obtain(
27
+ downEvent.downTime,
28
+ eventTime,
29
+ MotionEvent.ACTION_MOVE,
30
+ 1, // pointerCounts
31
+ arrayOf(pointerProperties),
32
+ arrayOf(pointerCoords),
33
+ 0, // metaState
34
+ downEvent.buttonState,
35
+ downEvent.xPrecision,
36
+ downEvent.yPrecision,
37
+ 0, // deviceId
38
+ 0, // edgeFlags
39
+ downEvent.source,
40
+ 0
41
+ )
42
+ }
14
43
 
15
44
  fun obtainDownEvent(x: Float, y: Float, precision: FloatArray = PRECISION)
16
45
  = obtainDownEvent(x, y, precision, null)
@@ -7,6 +7,7 @@ import com.wix.invoke.types.ClassTarget;
7
7
  import com.wix.invoke.types.Invocation;
8
8
  import com.wix.invoke.types.InvocationTarget;
9
9
 
10
+ import org.json.JSONArray;
10
11
  import org.json.JSONException;
11
12
  import org.json.JSONObject;
12
13
  import org.junit.Test;
@@ -21,20 +22,20 @@ public class JsonParserTest {
21
22
  @Test
22
23
  public void targetClassStaticMethodNoParams() {
23
24
  Invocation invocation = new Invocation(new ClassTarget("java.lang.System"), "lineSeparator");
24
- assertThat(parse("targetClassStaticMethodNoParams.json")).isEqualToComparingFieldByFieldRecursively(invocation);
25
+ assertThat(parse("targetClassStaticMethodNoParams.json")).usingRecursiveComparison().isEqualTo(invocation);
25
26
  }
26
27
 
27
28
  @Test
28
29
  public void parseTargetClassStaticMethodOneParam() {
29
30
  Invocation invocation = new Invocation(new ClassTarget("java.lang.String"), "valueOf", 1.0f);
30
- assertThat(parse("targetClassStaticMethodOneParam.json")).isEqualToComparingFieldByFieldRecursively(invocation);
31
+ assertThat(parse("targetClassStaticMethodOneParam.json")).usingRecursiveComparison().isEqualTo(invocation);
31
32
  }
32
33
 
33
34
  @Test
34
35
  public void targetInvocationMethodOfClassStaticMethodOneParam() {
35
36
  Invocation innerInvocation = new Invocation(new ClassTarget("java.lang.String"), "valueOf", 1.0f);
36
37
  Invocation outerInvocation = new Invocation(new InvocationTarget(innerInvocation), "length");
37
- assertThat(parse("targetInvocationMethodOfClassStaticMethodOneParam.json")).isEqualToComparingFieldByFieldRecursively(outerInvocation);
38
+ assertThat(parse("targetInvocationMethodOfClassStaticMethodOneParam.json")).usingRecursiveComparison().isEqualTo(outerInvocation);
38
39
  }
39
40
 
40
41
  @Test
@@ -46,7 +47,7 @@ public class JsonParserTest {
46
47
  Invocation perform = new Invocation(new InvocationTarget(onView), "perform", click);
47
48
 
48
49
 
49
- assertThat(parse("targetInvocationEspresso.json")).isEqualToComparingFieldByFieldRecursively(perform);
50
+ assertThat(parse("targetInvocationEspresso.json")).usingRecursiveComparison().isEqualTo(perform);
50
51
  }
51
52
 
52
53
 
@@ -59,7 +60,7 @@ public class JsonParserTest {
59
60
  Invocation click = new Invocation(new ClassTarget("android.support.test.espresso.action.ViewActions"), "click");
60
61
  Invocation perform = new Invocation(new ClassTarget("com.wix.detox.espresso.EspressoDetox"), "perform", onView, click);
61
62
 
62
- assertThat(parse("targetInvocationEspressoDetox.json")).isEqualToComparingFieldByFieldRecursively(perform);
63
+ assertThat(parse("targetInvocationEspressoDetox.json")).usingRecursiveComparison().isEqualTo(perform);
63
64
  }
64
65
 
65
66
  @Test
@@ -73,12 +74,27 @@ public class JsonParserTest {
73
74
  assertThat(parse("targetInvocationEspressoWebDetox.json")).usingRecursiveComparison().isEqualTo(tap);
74
75
  }
75
76
 
77
+ @Test
78
+ public void fromJsonTargetInvocationEspressoWebDetoxScript() throws JSONException {
79
+ Invocation getWebView = new Invocation(new ClassTarget("com.wix.detox.espresso.web.EspressoWebDetox"), "getWebView");
80
+ Invocation matcher = new Invocation(new ClassTarget("com.wix.detox.espresso.web.DetoxWebAtomMatcher"), "matcherForId", "textInput");
81
+ Invocation element = new Invocation(new InvocationTarget(getWebView), "element", matcher, 0);
82
+
83
+ String script = "function(el,arg1){}";
84
+ ArrayList<Object> scriptArguments = new ArrayList<>();
85
+ JSONArray arg1 = new JSONArray("[{ \"b\": true, \"n\": 1, \"s\": \"1\" }]");
86
+ scriptArguments.add(arg1);
87
+
88
+ Invocation runScriptWithArgs = new Invocation(new InvocationTarget(element), "runScriptWithArgs", script, scriptArguments);
89
+ assertThat(parse("targetInvocationEspressoWebDetoxScript.json")).usingRecursiveComparison().isEqualTo(runScriptWithArgs);
90
+ }
91
+
76
92
  @Test
77
93
  public void fromJsonTargetInvocationWithListParams() {
78
94
  ArrayList<String> params = new ArrayList<>();
79
95
  params.add(".*10.0.2.2.*");
80
96
  Invocation test = new Invocation(new ClassTarget("com.wix.detox.espresso.EspressoDetox"), "setURLBlacklist", params);
81
- assertThat(parse("fromJsonTargetInvocationWithListParams.json")).isEqualToComparingFieldByFieldRecursively(test);
97
+ assertThat(parse("fromJsonTargetInvocationWithListParams.json")).usingRecursiveComparison().isEqualTo(test);
82
98
  }
83
99
 
84
100
  public Invocation parseString(String jsonString) {
@@ -95,4 +111,4 @@ public class JsonParserTest {
95
111
  String jsonString = TestUtils.jsonFileToString(filePath);
96
112
  return parseString(jsonString);
97
113
  }
98
- }
114
+ }
@@ -0,0 +1,47 @@
1
+ {
2
+ "target":{
3
+ "type":"Invocation",
4
+ "value":{
5
+ "target":{
6
+ "type":"Invocation",
7
+ "value":{
8
+ "target":{
9
+ "type":"Class",
10
+ "value":"com.wix.detox.espresso.web.EspressoWebDetox"
11
+ },
12
+ "method":"getWebView",
13
+ "args":[
14
+
15
+ ]
16
+ }
17
+ },
18
+ "method":"element",
19
+ "args":[
20
+ {
21
+ "type":"Invocation",
22
+ "value":{
23
+ "target":{
24
+ "type":"Class",
25
+ "value":"com.wix.detox.espresso.web.DetoxWebAtomMatcher"
26
+ },
27
+ "method":"matcherForId",
28
+ "args":[
29
+ "textInput"
30
+ ]
31
+ }
32
+ },
33
+ {
34
+ "type":"Integer",
35
+ "value":0
36
+ }
37
+ ]
38
+ }
39
+ },
40
+ "method": "runScriptWithArgs",
41
+ "args": [
42
+ "function(el,arg1){}",
43
+ [
44
+ [{ "b": true, "n": 1, "s": "1" }]
45
+ ]
46
+ ]
47
+ }
package/index.d.ts CHANGED
@@ -1571,19 +1571,22 @@ declare global {
1571
1571
  moveCursorToEnd(): Promise<void>;
1572
1572
 
1573
1573
  /**
1574
- * Running a script on the element
1575
- * @param script a method that accept the element as its first arg
1576
- * @example function foo(element) { console.log(element); }
1577
- */
1578
- runScript(script: string): Promise<any>;
1579
-
1580
- /**
1581
- * Running a script on the element that accept args
1582
- * @param script a method that accept few args, and the element as the last arg.
1583
- * @param args a list of args to pass to the script
1584
- * @example function foo(a, b, c, element) { console.log(`${a}, ${b}, ${c}, ${element}`)}
1574
+ * Running a JavaScript function on the element.
1575
+ * The first argument to the function will be the element itself.
1576
+ * The rest of the arguments will be forwarded to the JavaScript function as is.
1577
+ *
1578
+ * @param script a callback function in stringified form, or a plain function reference
1579
+ * without closures, bindings etc. that will be converted to a string.
1580
+ * @param args optional args to pass to the script
1581
+ *
1582
+ * @example
1583
+ * await webElement.runScript('(el) => el.click()');
1584
+ * await webElement.runScript(function setText(element, text) {
1585
+ * element.textContent = text;
1586
+ * }, ['Custom Title']);
1585
1587
  */
1586
- runScriptWithArgs(script: string, args: any[]): Promise<any>;
1588
+ runScript(script: string, args?: unknown[]): Promise<any>;
1589
+ runScript<F>(script: (...args: any[]) => F, args?: unknown[]): Promise<F>;
1587
1590
 
1588
1591
  /**
1589
1592
  * Gets the current page url
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "detox",
3
3
  "description": "E2E tests and automation for mobile",
4
- "version": "20.13.1-smoke.0",
4
+ "version": "20.13.2-smoke.0",
5
5
  "bin": {
6
6
  "detox": "local-cli/cli.js"
7
7
  },
@@ -109,5 +109,5 @@
109
109
  "browserslist": [
110
110
  "node 14"
111
111
  ],
112
- "gitHead": "d43265d95231032ed53eea6d0ef87d689d61c5e8"
112
+ "gitHead": "1365e1f670eb41459b20be4ef732a87037ab899b"
113
113
  }
@@ -1,5 +1,7 @@
1
1
  const DetoxRuntimeError = require('../../errors/DetoxRuntimeError');
2
2
  const invoke = require('../../invoke');
3
+ const assertIsFunction = require('../../utils/assertIsFunction');
4
+ const isArrowFunction = require('../../utils/isArrowFunction');
3
5
  const actions = require('../actions/web');
4
6
  const EspressoWebDetoxApi = require('../espressoapi/web/EspressoWebDetox');
5
7
  const WebViewElementApi = require('../espressoapi/web/WebViewElement');
@@ -73,12 +75,14 @@ class WebElement {
73
75
  return await new ActionInteraction(this[_invocationManager], new actions.WebMoveCursorEnd(this)).execute();
74
76
  }
75
77
 
76
- async runScript(script) {
77
- return await new ActionInteraction(this[_invocationManager], new actions.WebRunScriptAction(this, script)).execute();
78
- }
78
+ async runScript(maybeFunction, args) {
79
+ const script = stringifyScript(maybeFunction);
79
80
 
80
- async runScriptWithArgs(script, args) {
81
- return await new ActionInteraction(this[_invocationManager], new actions.WebRunScriptWithArgsAction(this, script, args)).execute();
81
+ if (args) {
82
+ return await new ActionInteraction(this[_invocationManager], new actions.WebRunScriptWithArgsAction(this, script, args)).execute();
83
+ } else {
84
+ return await new ActionInteraction(this[_invocationManager], new actions.WebRunScriptAction(this, script)).execute();
85
+ }
82
86
  }
83
87
 
84
88
  async getCurrentUrl() {
@@ -120,6 +124,20 @@ class WebViewElement {
120
124
  }
121
125
  }
122
126
 
127
+ function stringifyScript(maybeFunction) {
128
+ if (typeof maybeFunction !== 'string' && typeof maybeFunction !== 'function') {
129
+ return maybeFunction;
130
+ }
131
+
132
+ const script = (typeof maybeFunction === 'function' ? maybeFunction.toString() : assertIsFunction(maybeFunction)).trim();
133
+ // WebElement interactions don't support arrow functions for some reason.
134
+ if (isArrowFunction(script)) {
135
+ return `function arrowWorkaround() { return (${script}).apply(this, arguments); }`;
136
+ }
137
+
138
+ return script;
139
+ }
140
+
123
141
  module.exports = {
124
142
  WebElement,
125
143
  WebViewElement,
@@ -76,10 +76,7 @@ class WebElement {
76
76
  return {
77
77
  target: element,
78
78
  method: "runScriptWithArgs",
79
- args: [script, {
80
- type: "ArrayList<Object>",
81
- value: args
82
- }]
79
+ args: [script, args]
83
80
  };
84
81
  }
85
82
 
@@ -0,0 +1,35 @@
1
+ const isArrowFunction = require('./isArrowFunction');
2
+
3
+ const EXAMPLE = `Here are some examples of valid function strings:
4
+
5
+ 1. function(el) { el.click(); }
6
+ 2. el => el.click()
7
+ 3. (el) => el.click()
8
+ `;
9
+
10
+ /**
11
+ * Dynamically evaluates a string as a function and throws an error if it's not a function
12
+ * @param {string} str serialized function like 'function() { return 42; }'
13
+ */
14
+ function assertIsFunction(str) {
15
+ let isFunction;
16
+
17
+ try {
18
+ isFunction = isFunctionDeclaration(str) && Function(`return typeof (${str})`)() === 'function';
19
+ } catch (e) {
20
+ isFunction = false;
21
+ }
22
+
23
+ if (!isFunction) {
24
+ throw new TypeError(`Expected a valid function string, but got: ${str}\n\n${EXAMPLE}`);
25
+ }
26
+
27
+ return str;
28
+ }
29
+
30
+ function isFunctionDeclaration(rawStr) {
31
+ const str = rawStr.trimStart();
32
+ return str.startsWith('async') || str.startsWith('function') || isArrowFunction(str);
33
+ }
34
+
35
+ module.exports = assertIsFunction;
@@ -0,0 +1,24 @@
1
+ function isArrowFunction(code) {
2
+ if (!code.includes('=>')) {
3
+ return false;
4
+ }
5
+
6
+ const syncCode = removeAsync(code.trimStart());
7
+ return syncCode.startsWith('(') || isSimpleArrowFunction(code);
8
+ }
9
+
10
+ function removeAsync(code) {
11
+ return code.startsWith('async') ? code.slice(5).trimStart() : code;
12
+ }
13
+
14
+ function isSimpleArrowFunction(code) {
15
+ const [signature] = code.split('=>', 1);
16
+
17
+ return isAlphanumericId(removeAsync(signature.trim()));
18
+ }
19
+
20
+ function isAlphanumericId(code) {
21
+ return /^[a-zA-Z0-9]+$/.test(code);
22
+ }
23
+
24
+ module.exports = isArrowFunction;
@@ -1 +0,0 @@
1
- f11641164a4f2ccb3b0b9de91e399646
@@ -1 +0,0 @@
1
- 97c103ba6e127dbe2dc1b47a972aa3ae9a4e1d65
@@ -1 +0,0 @@
1
- 00f9de5a01b9153372c3675054b3cfbcdafa40c5ce88ba851ef71e17d0b61454
@@ -1 +0,0 @@
1
- c88f0877227029128911cdb592c899db3431279e3338ab0b28aef8a6dff658384d628aebf05b08538adb3127ca3d897cc7241101e722965560100015b3cb0bba
@@ -1 +0,0 @@
1
- 1b4b53835ca72328129cda1007497a31
@@ -1 +0,0 @@
1
- 3e27db4c54c0ce44edfef999eef17d8d326f2a70
@@ -1 +0,0 @@
1
- 11b9a7566d6654e66fbfb76a92da02bfbab8c97463199839590d2c0ea2307dc4
@@ -1 +0,0 @@
1
- ba73a0da52b6d571c6aa370df12e4f65db8424dcdb2450f83825d9abf0faf3f54211eec8d392dc689a191e09aff1396312a551b280d17710d7bb4cc8d2e2e356
@@ -1 +0,0 @@
1
- 02670d8571dd840d7c1e604d43356b33
@@ -1 +0,0 @@
1
- 4580dad60e33036c50d19b34a9fe021be5304ac8
@@ -1 +0,0 @@
1
- d843d03b68588878b7afdcd99421527b3a60145afb450f01e7aea0263c9232ea
@@ -1 +0,0 @@
1
- f6ac58b1b02c9fe567cb29c2ecdf28f8ef7fb092438eafcbdcb7f2ba5a64f7a4a725d1d6a021421b19ea78f619feead3051ff129164a25e0e031985f1e635539
@@ -1 +0,0 @@
1
- bfae4a3d65c10d4f5e1720d34350c38c
@@ -1 +0,0 @@
1
- c963c4f616a8a6a534567a173f313b49937ae402
@@ -1 +0,0 @@
1
- d12f147001264686f12bc4b1b3af172aa4c55a704f12cb31e328ad4f0fd5d8f5
@@ -1 +0,0 @@
1
- 917b7c2836e3f46c1bc94c01bdd819b740e4d45e197aac6cf80cbaf9e84f3e582d3c43cfdb31d68ce1cf2673b900b5f9b7c52ec94e005eb6ac113050e54399f6