Repository navigation
test(e2e): port the native e2e suites, add impact analysis - #3925
Conversation
This reverts commit ad77ff1.
| supportedReactions={supportedReactions} | ||
| type={reaction.type} | ||
| /> | ||
| {/* Identifies each reaction type for e2e tests; adds no layout of its own. */} |
There was a problem hiding this comment.
A testID stops Fabric from flattening a View, so this wrapper adds up to 4 native views per message row (the default before they add the number thingy). Let's put it on the icon instead:
| {/* Identifies each reaction type for e2e tests; adds no layout of its own. */} | |
| <Icon | |
| size={icon.size} | |
| style={[styles.iconStyle, icon.style]} | |
| supportedReactions={supportedReactions} | |
| testID={`reaction-list-item-${reaction.type}`} | |
| type={reaction.type} | |
| /> |
We'd then also have to forward it, so Props (above) gets 'testID', Icon passes it to ReactionIcon and so on down the chain.
| accessibilityLabel={title} | ||
| accessibilityRole='text' | ||
| style={[!messageFromContext?.quoted_message ? styles.wrapper : null, wrapper]} | ||
| testID={messageFromContext?.quoted_message ? 'quoted-message' : 'reply-composer-preview'} |
There was a problem hiding this comment.
This root View was flattened before. container is already a native view and still wraps the text:
| testID={messageFromContext?.quoted_message ? 'quoted-message' : 'reply-composer-preview'} | |
| > | |
| <View | |
| style={[styles.container, container, stylesProp?.container]} | |
| testID={messageFromContext?.quoted_message ? 'quoted-message' : 'reply-composer-preview'} | |
| > |
| return ( | ||
| <CompositeAccessibilityProbe label={statusLabel}> | ||
| <View style={styles.container}> | ||
| <View style={styles.container} testID={statusTestID}> |
There was a problem hiding this comment.
This container is layout only, so the testID adds a native view per channel row (not going to be flattened with it). The icons are SVGs, so let's put it on them:
| <View style={styles.container} testID={statusTestID}> | |
| <View style={styles.container}> | |
| {messageStatus === MessageStatusTypes.SENDING ? ( | |
| <icons.Time | |
| stroke={semantics.chatTextTimestamp} | |
| height={16} | |
| width={16} | |
| testID='channel-preview-status-sending' | |
| {...timeIcon} | |
| /> | |
| ) : messageStatus === MessageStatusTypes.RECEIVED && | |
| status === MessageDeliveryStatus.READ ? ( | |
| <icons.CheckAll | |
| stroke={semantics.accentPrimary} | |
| height={16} | |
| width={16} | |
| testID='channel-preview-status-read' | |
| {...checkAllIcon} | |
| /> | |
| ) : status === MessageDeliveryStatus.DELIVERED ? ( | |
| <icons.CheckAll | |
| stroke={semantics.chatTextTimestamp} | |
| height={16} | |
| width={16} | |
| testID='channel-preview-status-delivered' | |
| {...checkAllIcon} | |
| /> | |
| ) : status === MessageDeliveryStatus.SENT ? ( | |
| <icons.Check | |
| stroke={semantics.chatTextTimestamp} | |
| height={16} | |
| width={16} | |
| testID='channel-preview-status-sent' | |
| {...checkIcon} | |
| /> |
(similar to how we did it in the last pr)
| get messageSender() { | ||
| return by.id('channel-preview-sender'); | ||
| }, | ||
| deliveryStatus(status: 'sending' | 'sent' | 'delivered' | 'read' | 'none') { |
There was a problem hiding this comment.
| deliveryStatus(status: 'sending' | 'sent' | 'delivered' | 'read' | 'none') { | |
| deliveryStatus(status: 'sending' | 'sent' | 'delivered' | 'read') { |
(since this will noop from the other comment)
|
|
||
| return ( | ||
| <View style={styles.reactionButton}> | ||
| <View style={styles.reactionButton} testID={`reaction-button-${type}`}> |
There was a problem hiding this comment.
This View was flattened before. Button passes the testID to its Pressable:
| <View style={styles.reactionButton} testID={`reaction-button-${type}`}> | |
| <View style={styles.reactionButton}> | |
| <Button | |
| testID={`reaction-button-${type}`} |
| </View> | ||
| </View> | ||
| <View style={styles.dismissWrapper}> | ||
| <View style={styles.dismissWrapper} testID='composer-link-preview-dismiss'> |
There was a problem hiding this comment.
dismissWrapper was flattened before. AttachmentRemoveControl passes the testID to its Pressable:
| <View style={styles.dismissWrapper} testID='composer-link-preview-dismiss'> | |
| <View style={styles.dismissWrapper}> | |
| <AttachmentRemoveControl onPress={dismissPreview} testID='composer-link-preview-dismiss' /> |
SDK Size
|
Ticket: https://linear.app/stream/issue/RN-449
🎯 Goal
Port the native iOS and Android e2e suites to the V10 Detox suite in
examples/E2ETestApp, and bring its CI up to the native SDKs: per-test impact analysis on pull requests, a nightly run that builds the coverage map, and Allure TestOps reporting.🛠 Implementation details
Tests
it.skipand a comment that links a ticket. That covers 72 tests, tracked in RN-489 to RN-506 and RN-510. With those skipped, 183 tests run.E2E app
@op-engineering/op-sqlite,<Chat enableOfflineSupport>). The database is wiped at login, so every test starts clean.setupCommandUIMiddlewarescall: since stream-chat10.0.0-rc.31(chore: stream-chat rc.31 compatibility #3919), the client installs the command middlewares itself.SDK
testIDs only (channel preview, reactions, link previews, unread indicators, swipe actions, and a few others). There is no behaviour change. One snapshot changed becauseScrollToBottomButtongot a newtestID.Impact analysis (
e2e/README.md, "Impact analysis")E2E_COVERAGE=1builds add a small Babel plugin (e2e/coverage/babelPlugin.js) that records which files run code. It isn't istanbul, because worklets capture istanbul's counters and then throw on the UI runtime.build_e2e_coverage_mapandselect_e2e_testsusefastlane-plugin-stream_actions(bumped from 0.4.14 to 0.4.19).Check E2E Requiredjob now also selects the tests, and skips e2e when none are selected.Build Androidbuilds the APKs once,Launch Allure TestOps (Android)opens one launch, andTest Androidruns up to 8 batches (one per selected test when fewer than 8 are selected), each taking a round-robin share of the selection.e2e-test-cron.yml, runs everything on Android with the coverage build and uploads thee2e-coverage-mapartifact. It also runs every test on iOS. Until its first run on the default branch, every PR runs all tests.Allure
examples/SampleApp/fastlane/Allurefile, the same layout as stream-chat-swift. A newallure_testcaselane creates test cases.ALLURE_TOKENrepository secret.Mock server
api_version=v2×tamps=ns. That mode comes from Add a nanosecond timestamps mode for stream-chat-js v10 stream-chat-test-mock-server#98, which is now merged intomain.🎨 UI Changes
None. The SDK changes are
testIDs only.🧪 Testing
yarn lint, E2ETestApptypecheckand the SDK unit tests pass.☑️ Checklist
developbranch (targetsV10: the suite needs the v10 SDK)examples/E2ETestApp/e2e/README.md)