detox 20.7.8-smoke.0 → 20.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. package/Detox-android/com/wix/detox/{20.7.8-smoke.0/detox-20.7.8-smoke.0-javadoc.jar → 20.9.0/detox-20.9.0-javadoc.jar} +0 -0
  2. package/Detox-android/com/wix/detox/20.9.0/detox-20.9.0-javadoc.jar.md5 +1 -0
  3. package/Detox-android/com/wix/detox/20.9.0/detox-20.9.0-javadoc.jar.sha1 +1 -0
  4. package/Detox-android/com/wix/detox/20.9.0/detox-20.9.0-javadoc.jar.sha256 +1 -0
  5. package/Detox-android/com/wix/detox/20.9.0/detox-20.9.0-javadoc.jar.sha512 +1 -0
  6. package/Detox-android/com/wix/detox/{20.7.8-smoke.0/detox-20.7.8-smoke.0-sources.jar → 20.9.0/detox-20.9.0-sources.jar} +0 -0
  7. package/Detox-android/com/wix/detox/20.9.0/detox-20.9.0-sources.jar.md5 +1 -0
  8. package/Detox-android/com/wix/detox/20.9.0/detox-20.9.0-sources.jar.sha1 +1 -0
  9. package/Detox-android/com/wix/detox/20.9.0/detox-20.9.0-sources.jar.sha256 +1 -0
  10. package/Detox-android/com/wix/detox/20.9.0/detox-20.9.0-sources.jar.sha512 +1 -0
  11. package/Detox-android/com/wix/detox/20.9.0/detox-20.9.0.aar +0 -0
  12. package/Detox-android/com/wix/detox/20.9.0/detox-20.9.0.aar.md5 +1 -0
  13. package/Detox-android/com/wix/detox/20.9.0/detox-20.9.0.aar.sha1 +1 -0
  14. package/Detox-android/com/wix/detox/20.9.0/detox-20.9.0.aar.sha256 +1 -0
  15. package/Detox-android/com/wix/detox/20.9.0/detox-20.9.0.aar.sha512 +1 -0
  16. package/Detox-android/com/wix/detox/{20.7.8-smoke.0/detox-20.7.8-smoke.0.pom → 20.9.0/detox-20.9.0.pom} +3 -3
  17. package/Detox-android/com/wix/detox/20.9.0/detox-20.9.0.pom.md5 +1 -0
  18. package/Detox-android/com/wix/detox/20.9.0/detox-20.9.0.pom.sha1 +1 -0
  19. package/Detox-android/com/wix/detox/20.9.0/detox-20.9.0.pom.sha256 +1 -0
  20. package/Detox-android/com/wix/detox/20.9.0/detox-20.9.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/build.gradle +3 -3
  29. package/android/detox/src/full/java/com/wix/detox/espresso/DetoxAction.java +5 -0
  30. package/android/detox/src/full/java/com/wix/detox/espresso/action/RNDetoxAccessibilityAction.kt +46 -0
  31. package/index.d.ts +7 -0
  32. package/package.json +4 -2
  33. package/src/android/actions/native.js +8 -0
  34. package/src/android/core/NativeElement.js +5 -0
  35. package/src/android/espressoapi/DetoxAction.js +12 -0
  36. package/src/ios/expectTwo.js +13 -0
  37. package/src/utils/invocationTraceDescriptions.js +1 -0
  38. package/Detox-android/com/wix/detox/20.7.8-smoke.0/detox-20.7.8-smoke.0-javadoc.jar.md5 +0 -1
  39. package/Detox-android/com/wix/detox/20.7.8-smoke.0/detox-20.7.8-smoke.0-javadoc.jar.sha1 +0 -1
  40. package/Detox-android/com/wix/detox/20.7.8-smoke.0/detox-20.7.8-smoke.0-javadoc.jar.sha256 +0 -1
  41. package/Detox-android/com/wix/detox/20.7.8-smoke.0/detox-20.7.8-smoke.0-javadoc.jar.sha512 +0 -1
  42. package/Detox-android/com/wix/detox/20.7.8-smoke.0/detox-20.7.8-smoke.0-sources.jar.md5 +0 -1
  43. package/Detox-android/com/wix/detox/20.7.8-smoke.0/detox-20.7.8-smoke.0-sources.jar.sha1 +0 -1
  44. package/Detox-android/com/wix/detox/20.7.8-smoke.0/detox-20.7.8-smoke.0-sources.jar.sha256 +0 -1
  45. package/Detox-android/com/wix/detox/20.7.8-smoke.0/detox-20.7.8-smoke.0-sources.jar.sha512 +0 -1
  46. package/Detox-android/com/wix/detox/20.7.8-smoke.0/detox-20.7.8-smoke.0.aar +0 -0
  47. package/Detox-android/com/wix/detox/20.7.8-smoke.0/detox-20.7.8-smoke.0.aar.md5 +0 -1
  48. package/Detox-android/com/wix/detox/20.7.8-smoke.0/detox-20.7.8-smoke.0.aar.sha1 +0 -1
  49. package/Detox-android/com/wix/detox/20.7.8-smoke.0/detox-20.7.8-smoke.0.aar.sha256 +0 -1
  50. package/Detox-android/com/wix/detox/20.7.8-smoke.0/detox-20.7.8-smoke.0.aar.sha512 +0 -1
  51. package/Detox-android/com/wix/detox/20.7.8-smoke.0/detox-20.7.8-smoke.0.pom.md5 +0 -1
  52. package/Detox-android/com/wix/detox/20.7.8-smoke.0/detox-20.7.8-smoke.0.pom.sha1 +0 -1
  53. package/Detox-android/com/wix/detox/20.7.8-smoke.0/detox-20.7.8-smoke.0.pom.sha256 +0 -1
  54. package/Detox-android/com/wix/detox/20.7.8-smoke.0/detox-20.7.8-smoke.0.pom.sha512 +0 -1
@@ -0,0 +1 @@
1
+ 12d1a9cfa955008ce7e6e8f43ef74da1
@@ -0,0 +1 @@
1
+ 4c7895239a15b9acae9679a26667e27631a2be19
@@ -0,0 +1 @@
1
+ 93cee9902249260f8f05a2659650938f4164b90daca144fc81a70b9263b36fa9
@@ -0,0 +1 @@
1
+ b65a42554b5d9a2eeac7d3b9001811f1e7a633b708b4dd841849a91eb7118f7ada259bb58700a08ec2d659b7035afead27aa800a9311a1514b00a04202bde7cb
@@ -0,0 +1 @@
1
+ 09f94e47a00171571d1738b4a3f75bb2
@@ -0,0 +1 @@
1
+ 8e9ec0a0059796344f457b77b4474039c976fdee
@@ -0,0 +1 @@
1
+ 121c023a311947235b10d14987a0de078f3760f9264ebe20ac061d47a334a376
@@ -0,0 +1 @@
1
+ 544a899292284a949f905f8c181236b39319980180f28b20d4e6827c9bfc1e1d01564d7ad44ca014f15e38aa572f528c9886b9e1d8825a577b86cc21235134db
@@ -0,0 +1 @@
1
+ e89d3204dcda439e4deb0df61603394a
@@ -0,0 +1 @@
1
+ eda5c226e954731b3dbd16becbab72f66888d5ce
@@ -0,0 +1 @@
1
+ 4da9ab41881efc27c7268bff2bfbb7092d9dbdf6de8f43787b4df649f0291bff
@@ -0,0 +1 @@
1
+ c63bf901eb0327ca3791b419f99dd67060a9b48a816da5c71e7e660e60fed607347ef8f76710969e9497054cc4f99add8db19f47b7e780ee3e6413df6d75e195
@@ -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.7.8-smoke.0</version>
6
+ <version>20.9.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>
@@ -63,13 +63,13 @@
63
63
  <dependency>
64
64
  <groupId>androidx.test</groupId>
65
65
  <artifactId>rules</artifactId>
66
- <version>1.4.0</version>
66
+ <version>1.5.0</version>
67
67
  <scope>compile</scope>
68
68
  </dependency>
69
69
  <dependency>
70
70
  <groupId>androidx.test.ext</groupId>
71
71
  <artifactId>junit</artifactId>
72
- <version>1.1.3</version>
72
+ <version>1.1.5</version>
73
73
  <scope>compile</scope>
74
74
  </dependency>
75
75
  <dependency>
@@ -0,0 +1 @@
1
+ acd9cc7c446bdbec5e2ed126330f8178
@@ -0,0 +1 @@
1
+ ec0e48ff2b6fb3fa8a114a10fab451a8386a1528
@@ -0,0 +1 @@
1
+ da04b622faa4f09ebc5395c8177812e905c42836f489147046d394e2f33aa7b3
@@ -0,0 +1 @@
1
+ 86b45511393ffa8d74be60e343701a364698a95c6f12135ee6fb207b9190ef611f14b7db0e90334b6ab53faac783ec46164a03e2ebde217c5d75e3e86e3075f6
@@ -3,11 +3,11 @@
3
3
  <groupId>com.wix</groupId>
4
4
  <artifactId>detox</artifactId>
5
5
  <versioning>
6
- <latest>20.7.8-smoke.0</latest>
7
- <release>20.7.8-smoke.0</release>
6
+ <latest>20.9.0</latest>
7
+ <release>20.9.0</release>
8
8
  <versions>
9
- <version>20.7.8-smoke.0</version>
9
+ <version>20.9.0</version>
10
10
  </versions>
11
- <lastUpdated>20230503131305</lastUpdated>
11
+ <lastUpdated>20230509160449</lastUpdated>
12
12
  </versioning>
13
13
  </metadata>
@@ -1 +1 @@
1
- 12770a9d4f6d8e755279d548b81a0a48
1
+ 7053662d2e33fbb9e98df25bdd415049
@@ -1 +1 @@
1
- 680e7072bb92861c38c84417961ae7f8f0fa1522
1
+ 6940fcfbcba3f2f2fe28a0c8990e4a73acc1b850
@@ -1 +1 @@
1
- f911526e429ded942d8a8554affb4e15bec56698257b79affc9d6bb455bae029
1
+ de9c81ebd4571c1447448f166bdf72b47fac675208c055934ee0f982aebb530e
@@ -1 +1 @@
1
- bb5353e380042c23cb29d7885f5de21b2868b6e9da50416822740f8d61ef6eb54535a0fa8e8389e4f1d3b80b57f0ed8cd054c15d2f12e5d70f8346e0825256c4
1
+ e1d52b19982e6266e8adfb8e891c5ed79258c8aac5dbd3628ee9b7adb072db79379c4bf742d596817abaff76737f7d80709bb884d2236fe831a39ce7af6d4b79
package/Detox-ios-src.tbz CHANGED
Binary file
package/Detox-ios.tbz CHANGED
Binary file
@@ -102,10 +102,10 @@ dependencies {
102
102
  api('org.hamcrest:hamcrest:2.2') {
103
103
  because 'See https://github.com/wix/Detox/issues/3920. Need to force hamcrest 2.2 win in battle of 2.2 vs. 1.3 (specified by Espresso).'
104
104
  }
105
- api('androidx.test:rules:1.4.0') {
105
+ api('androidx.test:rules:1.5.0') {
106
106
  because 'of ActivityTestRule. Needed by users *and* internally used by Detox.'
107
107
  }
108
- api('androidx.test.ext:junit:1.1.3') {
108
+ api('androidx.test.ext:junit:1.1.5') {
109
109
  because 'Needed so as to seamlessly provide AndroidJUnit4 to Detox users. Depends on junit core.'
110
110
  }
111
111
 
@@ -136,7 +136,7 @@ dependencies {
136
136
  testImplementation 'org.json:json:20140107'
137
137
 
138
138
  // https://github.com/spekframework/spek/issues/232#issuecomment-610732158
139
- testRuntimeOnly 'org.junit.vintage:junit-vintage-engine:5.6.0'
139
+ testRuntimeOnly 'org.junit.vintage:junit-vintage-engine:5.7.2'
140
140
 
141
141
  testImplementation 'org.assertj:assertj-core:3.16.1'
142
142
  testImplementation "org.jetbrains.kotlin:kotlin-test:$_kotlinVersion"
@@ -5,6 +5,7 @@ import android.os.Build;
5
5
 
6
6
  import com.wix.detox.common.DetoxErrors.DetoxRuntimeException;
7
7
  import com.wix.detox.common.DetoxErrors.StaleActionException;
8
+ import com.wix.detox.espresso.action.RNDetoxAccessibilityAction;
8
9
  import com.wix.detox.espresso.action.AdjustSliderToPositionAction;
9
10
  import com.wix.detox.espresso.action.DetoxMultiTap;
10
11
  import com.wix.detox.espresso.action.RNClickAction;
@@ -203,6 +204,10 @@ public class DetoxAction {
203
204
  };
204
205
  }
205
206
 
207
+ public static ViewAction accessibilityAction(final String actionName) {
208
+ return new RNDetoxAccessibilityAction(actionName);
209
+ }
210
+
206
211
  private static Date parseDateISO8601(String dateString) throws ParseException {
207
212
  try {
208
213
  return new SimpleDateFormat(ISO8601_FORMAT).parse(dateString);
@@ -0,0 +1,46 @@
1
+ package com.wix.detox.espresso.action
2
+
3
+ import android.view.View
4
+ import androidx.test.espresso.UiController
5
+ import androidx.test.espresso.ViewAction
6
+ import com.facebook.react.bridge.Arguments
7
+ import com.facebook.react.bridge.ReactContext
8
+ import com.facebook.react.bridge.WritableMap
9
+ import com.facebook.react.uimanager.UIManagerHelper
10
+ import com.facebook.react.uimanager.events.Event
11
+ import com.wix.detox.espresso.DetoxMatcher
12
+ import org.hamcrest.Matcher
13
+
14
+ class RNDetoxAccessibilityAction(private val mActionName: String) : ViewAction {
15
+
16
+ override fun getConstraints(): Matcher<View?>? = DetoxMatcher.matcherForNotNull()
17
+
18
+ override fun getDescription(): String = "Dispatch an Accessibility Action"
19
+
20
+ override fun perform(uiController: UiController?, view: View?) {
21
+ val reactContext = view?.context as? ReactContext ?: return
22
+ val reactTag = view.id
23
+
24
+ UIManagerHelper.getEventDispatcherForReactTag(reactContext, reactTag)
25
+ ?.dispatchEvent(
26
+ TopAccessibilityEvent(
27
+ surfaceId = UIManagerHelper.getSurfaceId(reactContext),
28
+ viewId = reactTag,
29
+ actionName = mActionName,
30
+ )
31
+ )
32
+
33
+ val waitTimeMS = 100
34
+ uiController!!.loopMainThreadForAtLeast(waitTimeMS.toLong())
35
+ }
36
+ }
37
+
38
+ class TopAccessibilityEvent(surfaceId: Int, viewId: Int, private val actionName: String) :
39
+ Event<TopAccessibilityEvent>(surfaceId, viewId) {
40
+
41
+ override fun getEventName(): String = "topAccessibilityAction"
42
+
43
+ override fun getEventData(): WritableMap? {
44
+ return Arguments.createMap().apply { putString("actionName", actionName) }
45
+ }
46
+ }
package/index.d.ts CHANGED
@@ -1380,6 +1380,13 @@ declare global {
1380
1380
  */
1381
1381
  setDatePickerDate(dateString: string, dateFormat: string): Promise<void>;
1382
1382
 
1383
+ /**
1384
+ * Triggers a given [accessibility action]{@link https://reactnative.dev/docs/accessibility#accessibility-actions}.
1385
+ * @param actionName - name of the accessibility action
1386
+ * @example await element(by.id('view')).performAccessibilityAction('activate');
1387
+ */
1388
+ performAccessibilityAction(actionName: string): Promise<void>
1389
+
1383
1390
  /**
1384
1391
  * Pinches in the given direction with speed and angle. (iOS only)
1385
1392
  * @param angle value in radiant, default is `0`
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.7.8-smoke.0",
4
+ "version": "20.9.0",
5
5
  "bin": {
6
6
  "detox": "local-cli/cli.js"
7
7
  },
@@ -24,6 +24,8 @@
24
24
  "build:android-native": "cd android && ./gradlew publish -Dversion=999.999.999 -DbuildFlavour=coreNative -DforceLocal=true && cd ..",
25
25
  "lint": "eslint .",
26
26
  "unit": "jest --coverage --verbose",
27
+ "unit:android-debug": "cd android && ./gradlew testFullDebug",
28
+ "unit:android-release": "cd android && ./gradlew testFullRelease",
27
29
  "pretest": "npm run lint",
28
30
  "test": "npm run unit",
29
31
  "posttest": "cp coverage/lcov.info coverage/unit.lcov",
@@ -200,5 +202,5 @@
200
202
  }
201
203
  }
202
204
  },
203
- "gitHead": "7a0e32ee4ba5fc236437ccfbeb285b41cde7d762"
205
+ "gitHead": "0d183a6fc5f3c6ba250ed7eba3393e169e72bea4"
204
206
  }
@@ -145,6 +145,13 @@ class TakeElementScreenshot extends Action {
145
145
  }
146
146
  }
147
147
 
148
+ class AccessibilityActionAction extends Action {
149
+ constructor(actionName) {
150
+ super();
151
+ this._call = invoke.callDirectly(DetoxActionApi.accessibilityAction(actionName));
152
+ }
153
+ }
154
+
148
155
  module.exports = {
149
156
  Action,
150
157
  TapAction,
@@ -164,4 +171,5 @@ module.exports = {
164
171
  ScrollToIndex,
165
172
  SetDatePickerDateAction,
166
173
  AdjustSliderToPosition,
174
+ AccessibilityActionAction
167
175
  };
@@ -169,6 +169,11 @@ class NativeElement {
169
169
  const traceDescription = actionDescription.adjustSliderToPosition(newPosition);
170
170
  return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
171
171
  }
172
+
173
+ async performAccessibilityAction(actionName) {
174
+ const traceDescription = actionDescription.performAccessibilityAction(actionName);
175
+ return await new ActionInteraction(this._invocationManager, this, new actions.AccessibilityActionAction(actionName), traceDescription).execute();
176
+ }
172
177
  }
173
178
 
174
179
  module.exports = {
@@ -233,6 +233,18 @@ class DetoxAction {
233
233
  };
234
234
  }
235
235
 
236
+ static accessibilityAction(actionName) {
237
+ if (typeof actionName !== "string") throw new Error("actionName should be a string, but got " + (actionName + (" (" + (typeof actionName + ")"))));
238
+ return {
239
+ target: {
240
+ type: "Class",
241
+ value: "com.wix.detox.espresso.DetoxAction"
242
+ },
243
+ method: "accessibilityAction",
244
+ args: [actionName]
245
+ };
246
+ }
247
+
236
248
  static parseDateISO8601(dateString) {
237
249
  if (typeof dateString !== "string") throw new Error("dateString should be a string, but got " + (dateString + (" (" + (typeof dateString + ")"))));
238
250
  return {
@@ -229,6 +229,13 @@ class Element {
229
229
  return this.withAction('clearText', traceDescription);
230
230
  }
231
231
 
232
+ performAccessibilityAction(actionName) {
233
+ if (typeof actionName !== 'string') throw new Error('actionName should be a string, but got ' + (actionName + (' (' + (typeof actionName + ')'))));
234
+
235
+ const traceDescription = actionDescription.performAccessibilityAction(actionName);
236
+ return this.withAction('accessibilityAction', traceDescription, actionName);
237
+ }
238
+
232
239
  scroll(pixels, direction = 'down', startPositionX = NaN, startPositionY = NaN) {
233
240
  if (!['left', 'right', 'up', 'down'].some(option => option === direction)) throw new Error('direction should be one of [left, right, up, down], but got ' + direction);
234
241
  if (typeof pixels !== 'number') throw new Error('amount of pixels should be a number, but got ' + (pixels + (' (' + (typeof pixels + ')'))));
@@ -660,6 +667,12 @@ class WaitFor {
660
667
  return this.waitForWithAction(traceDescription);
661
668
  }
662
669
 
670
+ performAccessibilityAction(actionName) {
671
+ this.action = this.actionableElement.performAccessibilityAction(actionName);
672
+ const traceDescription = actionDescription.performAccessibilityAction(actionName);
673
+ return this.waitForWithAction(traceDescription);
674
+ }
675
+
663
676
  pinch(scale, speed, angle) {
664
677
  this.action = this.actionableElement.pinch(scale, speed, angle);
665
678
  const traceDescription = actionDescription.pinch(scale, speed, angle);
@@ -7,6 +7,7 @@ module.exports = {
7
7
  longPressAndDrag: (duration, startX, startY, targetElement, endX, endY, speed, holdDuration) =>
8
8
  `long press and drag from ${startX}, ${startY} to ${endX}, ${endY} with speed ${speed} and hold duration ${holdDuration}`,
9
9
  multiTap: (times) => `tap ${times} times`,
10
+ performAccessibilityAction: (actionName) => `perform ${actionName} accessibilityAction`,
10
11
  pinch: (scale, speed, angle) => `pinch with scale ${scale}, speed ${speed}, and angle ${angle}`,
11
12
  pinchWithAngle: (direction, speed, angle) => `pinch with direction ${direction}, speed ${speed}, and angle ${angle}`,
12
13
  replaceText: (value) => `replace input text: "${value}"`,
@@ -1 +0,0 @@
1
- 61016340ff5600de9ad747d730680a7a
@@ -1 +0,0 @@
1
- 37c24264e9e760f3152b958f6a58b82628850064
@@ -1 +0,0 @@
1
- 901baff687dbfd1fc46afdfc3d34269d55506cb4c3eeaed8a6c92df22315ee74
@@ -1 +0,0 @@
1
- 7f87d1a65c5ad19e33a2aa5ce1c601741ffdf18b56fba8336d3f852bc4ebaf253f2fe87303ab4b225ae747b88647bcdc17644b35e51af72e31bd049daa623eea
@@ -1 +0,0 @@
1
- aee180246106d681db3aa8d519d9e27a
@@ -1 +0,0 @@
1
- 9ee53937cf4a14151ec43a8ca29a967366748a27
@@ -1 +0,0 @@
1
- 997d3a8a4b2d6fd51b4213966d2f7c546e1ebb6afeb6bc5e8495de143a7f66ec
@@ -1 +0,0 @@
1
- b58f279506325a8b4621ae0b7fccd726e1b7a01f208c3597a2500e042181ade1d6009a299cadf1968d66d612baae062b62a4149d4142275c00d7d9aef7eb72ca
@@ -1 +0,0 @@
1
- f62ab63d03ba71b4776965696f3d4a88
@@ -1 +0,0 @@
1
- 1a38f931edf9925af1d131a0e0a0822bd880dcc8
@@ -1 +0,0 @@
1
- 4145b5a8078b613e10205937ffb3da254d006fe78fbb169d8b2cedb3d02c021c
@@ -1 +0,0 @@
1
- ab25979faccc1aa8200a637ea866a5fc59e35bf340170673a01253ae8ce479fb5b7af87167dbde2d43d5b536f3fb350b34b478bbf75f5e87d5276940283a8ab6
@@ -1 +0,0 @@
1
- ce8a041d72a679e6f836a3f4c3821975
@@ -1 +0,0 @@
1
- 139bbd4ed5398cb999dd5fd12a2c9b77409ac2e3
@@ -1 +0,0 @@
1
- 4a017761e2e806b5bb8fac1d054c01cffdfb443129315073172ce3c7720bcecb
@@ -1 +0,0 @@
1
- 94585e8fd886448cc45aca119ed1dd1329f8d743ca902a0911743d7cee94baecae5ecfad1ba62ea8b9471b0fc251c23bfea4032c30f9231e5b8e97d933c8322c