-
-
Notifications
You must be signed in to change notification settings - Fork 344
test(e2e): Adds Feedback Widget Maestro E2E tests #4604
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
Conversation
Co-authored-by: Krystof Woldrich <[email protected]>
|
||
- runFlow: | ||
when: | ||
visible: 'Engine: Hermes for RN 0.77.1' # Skipping for 0.65.3 |
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.
As discussed and documented the Modal
implementation is fully supported on React Native 0.71 and up.
To avoid complicating the e2e-tests/cli.mjs
implementation to independently run each .yml
test in order to separate the feedback.yml
execution I skipped the test with Maestro. We can probably iterate by injecting the <FeedbackWidget>
form in the test App if we want to cover 0.65.3
with the E2E tests.
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.
Thank you for the note. The Modal is fully supported in 0.71 in the new architecture,
but for the legacy architecture, the test should pass (the modal should work) even for 0.65.3.
If it doesn't it might be unrelated to the modal, but we can discuss it.
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.
but for the legacy architecture, the test should pass (the modal should work) even for 0.65.3.
I haven't been able to successfully run the tests on 0.65.3 legacy architecture either. From the logs it seems that the modal does not open but I'll need to investigate this further to understand why this is happening.
iOSLogs
14:46:27.222 [ INFO] maestro.cli.runner.TestSuiteInteractor.invoke: Tap on id: feedback-button COMPLETED
14:46:27.222 [ INFO] maestro.cli.runner.TestSuiteInteractor.invoke: Assert that id: form-title is visible RUNNING
14:46:27.690 [ INFO] ios.xctest.XCTestIOSDevice.invoke: Device info DeviceInfo(widthPixels=1179, heightPixels=2556, widthPoints=393, heightPoints=852)
14:46:27.690 [ INFO] ios.IOSDevice.viewHierarchy: Requesting view hierarchy of the screen
14:46:28.428 [TRACE] ios.xctest.XCTestIOSDevice.invoke: Depth received: 14
14:46:28.431 [ INFO] ios.IOSDevice.viewHierarchy: Depth of the screen is 14
14:46:28.514 [ INFO] ios.xctest.XCTestIOSDevice.invoke: Device info DeviceInfo(widthPixels=1179, heightPixels=2556, widthPoints=393, heightPoints=852)
14:46:28.514 [ INFO] ios.IOSDevice.viewHierarchy: Requesting view hierarchy of the screen
14:46:28.830 [TRACE] ios.xctest.XCTestIOSDevice.invoke: Depth received: 14
14:46:28.831 [ INFO] ios.IOSDevice.viewHierarchy: Depth of the screen is 14
14:46:28.902 [ INFO] ios.xctest.XCTestIOSDevice.invoke: Device info DeviceInfo(widthPixels=1179, heightPixels=2556, widthPoints=393, heightPoints=852)
14:46:28.902 [ INFO] ios.IOSDevice.viewHierarchy: Requesting view hierarchy of the screen
14:46:29.190 [TRACE] ios.xctest.XCTestIOSDevice.invoke: Depth received: 14
14:46:29.190 [ INFO] ios.IOSDevice.viewHierarchy: Depth of the screen is 14
14:46:29.270 [ INFO] ios.xctest.XCTestIOSDevice.invoke: Device info DeviceInfo(widthPixels=1179, heightPixels=2556, widthPoints=393, heightPoints=852)
14:46:29.270 [ INFO] ios.IOSDevice.viewHierarchy: Requesting view hierarchy of the screen
14:46:29.618 [TRACE] ios.xctest.XCTestIOSDevice.invoke: Depth received: 14
14:46:29.618 [ INFO] ios.IOSDevice.viewHierarchy: Depth of the screen is 14
14:46:29.679 [ INFO] ios.xctest.XCTestIOSDevice.invoke: Device info DeviceInfo(widthPixels=1179, heightPixels=2556, widthPoints=393, heightPoints=852)
14:46:29.689 [ INFO] ios.IOSDevice.viewHierarchy: Requesting view hierarchy of the screen
14:46:29.948 [TRACE] ios.xctest.XCTestIOSDevice.invoke: Depth received: 14
14:46:29.948 [ INFO] ios.IOSDevice.viewHierarchy: Depth of the screen is 14
14:46:30.048 [ INFO] ios.xctest.XCTestIOSDevice.invoke: Device info DeviceInfo(widthPixels=1179, heightPixels=2556, widthPoints=393, heightPoints=852)
14:46:30.049 [ INFO] ios.IOSDevice.viewHierarchy: Requesting view hierarchy of the screen
14:46:30.806 [TRACE] ios.xctest.XCTestIOSDevice.invoke: Depth received: 14
14:46:30.817 [ INFO] ios.IOSDevice.viewHierarchy: Depth of the screen is 14
14:46:30.902 [ INFO] ios.xctest.XCTestIOSDevice.invoke: Device info DeviceInfo(widthPixels=1179, heightPixels=2556, widthPoints=393, heightPoints=852)
14:46:30.908 [ INFO] ios.IOSDevice.viewHierarchy: Requesting view hierarchy of the screen
14:46:31.247 [TRACE] ios.xctest.XCTestIOSDevice.invoke: Depth received: 14
14:46:31.249 [ INFO] ios.IOSDevice.viewHierarchy: Depth of the screen is 14
14:46:31.400 [ INFO] ios.xctest.XCTestIOSDevice.invoke: Device info DeviceInfo(widthPixels=1179, heightPixels=2556, widthPoints=393, heightPoints=852)
14:46:31.402 [ INFO] ios.IOSDevice.viewHierarchy: Requesting view hierarchy of the screen
14:46:31.761 [TRACE] ios.xctest.XCTestIOSDevice.invoke: Depth received: 14
14:46:31.775 [ INFO] ios.IOSDevice.viewHierarchy: Depth of the screen is 14
14:46:32.044 [ INFO] ios.xctest.XCTestIOSDevice.invoke: Device info DeviceInfo(widthPixels=1179, heightPixels=2556, widthPoints=393, heightPoints=852)
14:46:32.048 [ INFO] ios.IOSDevice.viewHierarchy: Requesting view hierarchy of the screen
14:46:32.336 [TRACE] ios.xctest.XCTestIOSDevice.invoke: Depth received: 14
14:46:32.371 [ INFO] ios.IOSDevice.viewHierarchy: Depth of the screen is 14
14:46:32.446 [ INFO] ios.xctest.XCTestIOSDevice.invoke: Device info DeviceInfo(widthPixels=1179, heightPixels=2556, widthPoints=393, heightPoints=852)
14:46:32.447 [ INFO] ios.IOSDevice.viewHierarchy: Requesting view hierarchy of the screen
14:46:32.696 [TRACE] ios.xctest.XCTestIOSDevice.invoke: Depth received: 14
14:46:32.696 [ INFO] ios.IOSDevice.viewHierarchy: Depth of the screen is 14
14:46:32.780 [ INFO] ios.xctest.XCTestIOSDevice.invoke: Device info DeviceInfo(widthPixels=1179, heightPixels=2556, widthPoints=393, heightPoints=852)
14:46:32.780 [ INFO] ios.IOSDevice.viewHierarchy: Requesting view hierarchy of the screen
14:46:33.078 [TRACE] ios.xctest.XCTestIOSDevice.invoke: Depth received: 14
14:46:33.079 [ INFO] ios.IOSDevice.viewHierarchy: Depth of the screen is 14
14:46:33.080 [ INFO] maestro.cli.runner.TestSuiteInteractor.invoke: Assert that id: form-title is visible FAILED
14:46:33.137 [ INFO] maestro.Maestro.takeScreenshot: Taking screenshot
14:46:33.154 [TRACE] maestro.utils.ScreenshotUtils.takeScreenshot: Taking screenshot to output sink
14:46:33.637 [ERROR] maestro.orchestra.Orchestra.executeCommands: [Command execution] CommandFailed: Assertion is false: id: form-title is visible
14:46:33.665 [ INFO] maestro.cli.runner.TestSuiteInteractor.invoke: Run feedback/happyFlow.yml FAILED
Android logs
14:42:41.038 [ INFO] maestro.cli.runner.TestSuiteInteractor.invoke: Tap on "Feedback" COMPLETED
14:42:41.038 [ INFO] maestro.cli.runner.TestSuiteInteractor.invoke: Tap on id: feedback-button RUNNING
14:42:41.130 [ INFO] maestro.Maestro.tap-BUbHBYE: Tapping on element: UiElement(treeNode=TreeNode(attributes={text=Report a Bug, accessibilityText=, hintText=, ignoreBoundsFiltering=false, resource-id=feedback-button, clickable=false, bounds=[171,569][274,594], enabled=true, focused=false, checked=false, scrollable=false, selected=false, class=android.widget.TextView}, children=[], clickable=false, enabled=true, focused=false, checked=false, selected=false), bounds=Bounds(x=171, y=569, width=103, height=25))
14:42:42.045 [ INFO] maestro.Maestro.tap-BUbHBYE: Refreshed element
14:42:42.046 [ INFO] maestro.Maestro.hierarchyBasedTap-hbl3e4M: Tapping at (222, 581) using hierarchy based logic for wait
14:42:42.046 [TRACE] maestro.utils.ScreenshotUtils.takeScreenshot: Taking screenshot to byte array
14:42:42.046 [TRACE] maestro.utils.ScreenshotUtils.takeScreenshot: Taking screenshot to output sink
14:42:43.411 [ INFO] maestro.Maestro.hierarchyBasedTap-hbl3e4M: Something have changed in the UI judging by view hierarchy. Proceed.
14:42:43.412 [ INFO] maestro.cli.runner.TestSuiteInteractor.invoke: Tap on id: feedback-button COMPLETED
14:42:43.412 [ INFO] maestro.cli.runner.TestSuiteInteractor.invoke: Assert that id: form-title is visible RUNNING
14:42:48.608 [ INFO] maestro.cli.runner.TestSuiteInteractor.invoke: Assert that id: form-title is visible FAILED
14:42:48.609 [ INFO] maestro.Maestro.takeScreenshot: Taking screenshot
14:42:48.609 [TRACE] maestro.utils.ScreenshotUtils.takeScreenshot: Taking screenshot to output sink
14:42:48.709 [ERROR] maestro.orchestra.Orchestra.executeCommands: [Command execution] CommandFailed: Assertion is false: id: form-title is visible
14:42:48.709 [ INFO] maestro.cli.runner.TestSuiteInteractor.invoke: Run feedback/happyFlow.yml FAILED
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.
Investigating this further it seems that the issue is not related to the Modal
but to the 'backgroundColor' not supported by native animations and causing a crash in older RN versions.
I've enabled the test for all RN versions with 9137fb3 and disabled the native driver for the backgroundColor
animation with 1a68b93 and cb20fbe
Note: I've also opened a PR on main
targetting the current beta feedback widget release. This also checks the RN version and enables the native driver for supported versions.
Android crash logs
Error: Style property 'backgroundColor' is not supported by native animated module
This error is located at:
in c
in f
in RCTView
in Unknown
in __Sentry.TouchEventBoundary
in Unknown
in RCTView
in Unknown
in RCTView
in Unknown
in u
Error: Style property 'backgroundColor' is not supported by native animated module
This error is located at:
in c
in f
in RCTView
in Unknown
in __Sentry.TouchEventBoundary
in Unknown
in RCTView
in Unknown
in RCTView
in Unknown
in u, stack:
validateStyles@221:4389
value@250:2140
value@226:2615
value@249:2877
value@226:2615
value@249:2274
value@249:1839
value@225:1674
value@250:1925
value@225:1674
value@224:3074
value@225:1674
value@241:639
r@242:1432
value@242:1611
value@220:2510
s@230:1060
start@230:1119
<unknown>@230:2366
forEach@-1
start@230:2247
value@736:3755
zl@59:65656
Va@59:81394
Va@-1
<unknown>@189:3836
Ha@59:79751
Ia@59:75906
Ia@-1
<unknown>@59:26275
<unknown>@189:3836
ht@59:26222
pt@59:26157
Ee@59:93057
Te@59:13008
Ce@59:13397
receiveTouches@59:14183
value@40:3537
<unknown>@40:730
value@40:2527
value@40:702
value@-1
Creating new dialog from context: com.rndiffapp.MainActivity@81c704c@136081484
FATAL EXCEPTION: main (Ask Gemini)
Process: com.rndiffapp, PID: 6044
com.facebook.react.bridge.JSApplicationIllegalArgumentException: disconnectAnimatedNodeFromView: Animated node with tag [6] does not exist
at com.facebook.react.animated.NativeAnimatedNodesManager.disconnectAnimatedNodeFromView(NativeAnimatedNodesManager.java:411)
at com.facebook.react.animated.NativeAnimatedModule$18.execute(NativeAnimatedModule.java:772)
at com.facebook.react.animated.NativeAnimatedModule.executeAllOperations(NativeAnimatedModule.java:258)
at com.facebook.react.animated.NativeAnimatedModule.access$400(NativeAnimatedModule.java:85)
at com.facebook.react.animated.NativeAnimatedModule$3.execute(NativeAnimatedModule.java:287)
at com.facebook.react.uimanager.UIViewOperationQueue$UIBlockOperation.execute(UIViewOperationQueue.java:579)
at com.facebook.react.uimanager.UIViewOperationQueue$1.run(UIViewOperationQueue.java:914)
at com.facebook.react.uimanager.UIViewOperationQueue.flushPendingBatches(UIViewOperationQueue.java:1025)
at com.facebook.react.uimanager.UIViewOperationQueue.access$2600(UIViewOperationQueue.java:47)
at com.facebook.react.uimanager.UIViewOperationQueue$DispatchUIFrameCallback.doFrameGuarded(UIViewOperationQueue.java:1085)
at com.facebook.react.uimanager.GuardedFrameCallback.doFrame(GuardedFrameCallback.java:29)
at com.facebook.react.modules.core.ReactChoreographer$ReactChoreographerDispatcher.doFrame(ReactChoreographer.java:175)
at com.facebook.react.modules.core.ChoreographerCompat$FrameCallback$1.doFrame(ChoreographerCompat.java:85)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1229)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1239)
at android.view.Choreographer.doCallbacks(Choreographer.java:899)
at android.view.Choreographer.doFrame(Choreographer.java:827)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1214)
at android.os.Handler.handleCallback(Handler.java:942)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7872)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
No tap action can be set up
failed to get buffer, invalid process token
Failed to transact (-32)
No tap action can be set up
Note that |
/> | ||
)} | ||
</View> | ||
|
||
{config.showName && ( | ||
<> | ||
<Text style={styles.label}> | ||
<Text style={styles.label} testID='name-label' accessibilityLabel={text.nameLabel}> |
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.
Do we need the additional testId
and accessibilityLabel
?
I would prefer not using the testIDs
if not needed to avoid conflicting with user apps.
If we need them then lets prefix them with something unique like sentry-feedback-*
.
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.
Updated with 8176d4f:
- I've cleaned up all the unneeded test-id and used the
sentry-feedback-*
prefix for those used. - Removed the unneeded accessibility labels.
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.
I would prefer not using the testIDs if not needed to avoid conflicting with user apps.
I ended up using both testID
's and text lookups since:
|
||
# The following tests are happy path tests for the feedback widget on both iOS and Android. | ||
# They verify that the feedback form can be opened, filled out, and submitted successfully. | ||
# The tests are separate because iOS tests work better with `testID` and Android tests work better with `text`. |
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.
The Android Test is super clean, sad that is doesn't work for iOS.
Is it flaky or the elements are not found?
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.
On iOS legacy text lookups fail consistently :(
Thank you for all the feedback @krystofwoldrich 🙇 |
# Conflicts: # dev-packages/e2e-tests/patch-scripts/rn.patch.app.js # packages/core/src/js/feedback/FeedbackWidgetProvider.tsx
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.
Nice E2E Tests! LGTM
📢 Type of change
Based on: #4726
PR Chain:
📜 Description
Adds Feedback Widget Maestro E2E tests for the happy path flow:
💡 Motivation and Context
Part of #4302
💚 How did you test it?
CI (submitted E2E test feedback), Manual
Note: To run Android locally you might need to change the build architecture android.patch
📝 Checklist
sendDefaultPII
is enabled🔮 Next steps
#skip-changelog