Skip to content

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

Merged
merged 248 commits into from
May 9, 2025

Conversation

antonis
Copy link
Collaborator

@antonis antonis commented Feb 26, 2025

📢 Type of change

  • Bugfix
  • New feature
  • Enhancement
  • Refactoring

Based on: #4726

PR Chain:

📜 Description

Adds Feedback Widget Maestro E2E tests for the happy path flow:

  • Show feedback button
  • Open the feedback widget
  • Fill and submit the form

💡 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

  • I added tests to verify changes
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled
  • I updated the docs if needed.
  • I updated the wizard if needed.
  • All tests passing
  • No breaking changes

🔮 Next steps

  • Add more tests outside the happy path

#skip-changelog


- runFlow:
when:
visible: 'Engine: Hermes for RN 0.77.1' # Skipping for 0.65.3
Copy link
Collaborator Author

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.

Copy link
Member

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.

Copy link
Collaborator Author

@antonis antonis Apr 29, 2025

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

Copy link
Collaborator Author

@antonis antonis Apr 30, 2025

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

@antonis antonis marked this pull request as ready for review April 28, 2025 08:37
@antonis
Copy link
Collaborator Author

antonis commented Apr 28, 2025

Note that End-to-End Tests / metrics (new, ios) (pull_request) already fail in the feature branch PR and will be handled with #4784

/>
)}
</View>

{config.showName && (
<>
<Text style={styles.label}>
<Text style={styles.label} testID='name-label' accessibilityLabel={text.nameLabel}>
Copy link
Member

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-*.

Copy link
Collaborator Author

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.

Copy link
Collaborator Author

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:

@antonis antonis marked this pull request as draft April 30, 2025 11:17

# 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`.
Copy link
Member

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?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@antonis antonis marked this pull request as ready for review April 30, 2025 16:32
@antonis
Copy link
Collaborator Author

antonis commented Apr 30, 2025

Thank you for all the feedback @krystofwoldrich 🙇
This is now ready for another pass 🙏

@antonis antonis requested a review from krystofwoldrich April 30, 2025 16:39
# Conflicts:
#	dev-packages/e2e-tests/patch-scripts/rn.patch.app.js
#	packages/core/src/js/feedback/FeedbackWidgetProvider.tsx
Copy link
Collaborator

@lucas-zimerman lucas-zimerman left a 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

@antonis antonis merged commit 92c4d2d into feedback-ui-2 May 9, 2025
69 checks passed
@antonis antonis deleted the antonis/feedback-e2e branch May 9, 2025 07:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants