Automated tests for Unread Indicators feature and final polish#10929
Conversation
|
npm has a |
Add mock Fix UrbanAirship mock Get main drawer to render rename to navigation test Just render the sidebar links for now Fix tests and make ReportScreen render Add report action and verify the action renders Test for report-action-item visibility Mock disconnect for Pusher add way to set initial url for testing; Test for drawer status Test for the unread indicator Mock local notification and make sure only one notification appears upgrade test library dependencies and use act to get rid of weird warning undo test version bumps Fix tests Add comment Test behavior of unread indicator in report and sidebar Rename back to unread indicators Test new messages badge indicator refactor and improve Report screen visibility check Update mock for AppState Clear new line indicator when report page is in view and we return from background remove extra logs add JSDocs Check the LHN lastMessageText Fix ReportTest Check for pendingAction when deleting comment Fix deleted comments not showing strikethrough while offline Stop allowing deletion or editing of pendingAction add comments as users cannot be updated correctly via sequenceNumber Rollback some changes Use sequenceNumber for handledReportActions for now Remove log add doc
ca20849 to
b199711
Compare
|
This one is testing well for me locally, but going to wait until the Auth PR for |
| Onyx.merge(ONYXKEYS.PERSONAL_DETAILS, { | ||
| [USER_B_EMAIL]: TestHelper.buildPersonalDetails(USER_B_EMAIL, USER_B_ACCOUNT_ID, 'B'), | ||
| }); | ||
| await waitForPromisesToResolve(); |
There was a problem hiding this comment.
Again here, adding await to each of the merge() methods should allow this waitForPromisesToResolve() to be removed.
There was a problem hiding this comment.
Ah in this case, I think we are not just waiting for Onyx.merge() but also some fun stuff that "eventually happens" after the merge.
There was a problem hiding this comment.
Hm, maybe this is the cause to some of my test failures that I'm seeing on my new sidebarlinks PR. I need to explore it further.
marcochavezf
left a comment
There was a problem hiding this comment.
Nice! 🔥 Just a few comments
…work. Use regular promises in the actual tests themselves
|
Reworked the tests here a bunch based on @tgolen's feedback. Feeling pretty good about the changes. The one thing I'm not 100% sure on is the usage of App/tests/utils/waitForPromisesToResolveWithAct.js Lines 1 to 21 in 7b76284 |
PauloGasparSv
left a comment
There was a problem hiding this comment.
My dev env is really buggy (not sending notifications correctly, duplicating messages, only working correctly while debugging) this past week so for now I'll approve the code for the changes I've read and I'll leave the tests for the other reviewers.
neil-marcellini
left a comment
There was a problem hiding this comment.
I've only looked at this a bit so far, but it's really cool! For now, I have a few questions:
| * | ||
| * @returns {RenderAPI} | ||
| */ | ||
| function signInAndGetAppWithUnreadChat() { |
There was a problem hiding this comment.
NAB: For future tests it would be nice to have a signInAndGetApp function, maybe in TestHelpers.js. I imagine most ui tests in the future will need to start with that.
There was a problem hiding this comment.
Great point. I think there's also a chance that a lot of UI tests could not need this since they might test more isolated individual components and not flows that require navigation. I think this would be good to add in a future PR though once there is a second test that needs this behavior.
tgolen
left a comment
There was a problem hiding this comment.
Wow, those tests are looking great now!
| @@ -0,0 +1 @@ | |||
| export default {}; | |||
There was a problem hiding this comment.
Would it be OK if we also make a requirement that any mock file also should have an explanation for why it's mocked? I think that would be super helpful.
There was a problem hiding this comment.
I think that sounds great. The answer won't always be the same so it is good context to add for sure and also will help people understand all the reasons why something could or should be mocked.
There was a problem hiding this comment.
But also would say we can do that in a cleanup step.
| // The main app uses a NativeModule called BootSplash to show/hide a splash screen. Since we can't use this in the node environment | ||
| // where tests run we simulate a behavior where the splash screen is always hidden (similar to web which has no splash screen at all). |
There was a problem hiding this comment.
❤️ I love this comment. It makes it so clear why the mock is necessary!
| // Scroll and verify that the new messages badge is also hidden | ||
| scrollUpToRevealNewMessagesBadge(renderedApp); | ||
| expect(isNewMessagesBadgeVisible(renderedApp)).toBe(false); | ||
| }); |
There was a problem hiding this comment.
This looks great with the promises!!
| Onyx.merge(ONYXKEYS.PERSONAL_DETAILS, { | ||
| [USER_C_EMAIL]: TestHelper.buildPersonalDetails(USER_C_EMAIL, USER_C_ACCOUNT_ID, 'C'), | ||
| }); | ||
| return waitForPromisesToResolve(); |
There was a problem hiding this comment.
Something else I did in the LHN tests was to use return Onyx.multiSet() which would prevent you from needing to deal with three separate promises here and can remove another waitForPromisesToResolve.
But in that case, I think we also need to wrap them in act() to ensure all the component tree is updated properly before making assertions. I have yet to test that out fully.
That also assume that using set() is OK (which I think it usually is for tests).
There was a problem hiding this comment.
Gonna leave this one - mainly because having a few different merges happen seems closer to what would happen in the UI.
| import {act} from '@testing-library/react-native'; | ||
| import waitForPromisesToResolve from './waitForPromisesToResolve'; | ||
|
|
||
| /** |
There was a problem hiding this comment.
I love this comment, but what's not clear to me is when it should be used. Is there some guidance that can be added for that? Like... "Use when..." and "Do not use when..."
|
Updated. Thanks for the additional comments @tgolen and @neil-marcellini |
|
npm has a |
Gonna go for the merge here as it did not seem like there was any major pushback from @marcochavezf or @neil-marcellini
|
@marcaaron looks like this was merged without passing tests. Please add a note explaining why this was done and remove the |
|
Oh shoot are we supposed to add a reviewer checklist in a comment or edit the description? I’m not sure 🥲 This was not an emergency. Just the contributor checklist check. |
|
🚀 Deployed to staging by @marcaaron in version: 1.2.2-0 🚀
|
|
🚀 Deployed to production by @luacmartins in version: 1.2.2-0 🚀
|
Details
There are several changes introduced in this PR, but most of them exist to enable UI testing for the entire app.
pendingAction === 'add'(this is temporary but I noticed this feature is pretty broken so disabled it for now until we are totally migrated to usingreportActionIDforreportAction_*values keys)sequenceNumberwere being set toclientIDwhich made it impossible to mark a "pending" comment as unread. Instead we use a guessedsequenceNumberfor this. I suspect this may need to change in the future or depend onreportActionIDas well.typefield (Fixed)previousMessagefield that we can use as a fallback.Fixed Issues
$ https://github.com/Expensify/Expensify/issues/228076
$ #10799
$ #10753
Tests
Testing Unread LHN Status, “New Messages” badge, and New Line Indicator
Testing Deleted Comment Edge Case
PR Review Checklist
Contributor (PR Author) Checklist
### Fixed Issuessection aboveTestssectionQA stepssectiontoggleReportand notonIconClick)src/languages/*filesSTYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)/** comment above it */displayNamepropertythisproperly so there are no scoping issues (i.e. foronClick={this.submit}the methodthis.submitshould be bound tothisin the constructor)thisare necessary to be bound (i.e. avoidthis.submit = this.submit.bind(this);ifthis.submitis never passed to a component event handler likeonClick)StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG)Avataris modified, I verified thatAvataris working as expected in all cases)PR Reviewer Checklist
The Contributor+ will copy/paste it into a new comment and complete it after the author checklist is completed
### Fixed Issuessection aboveTestssectionQA stepssectiontoggleReportand notonIconClick).src/languages/*filesSTYLE.md) were followedAvatar, I verified the components usingAvatarhave been tested & I retested again)/** comment above it */displayNamepropertythisproperly so there are no scoping issues (i.e. foronClick={this.submit}the methodthis.submitshould be bound tothisin the constructor)thisare necessary to be bound (i.e. avoidthis.submit = this.submit.bind(this);ifthis.submitis never passed to a component event handler likeonClick)StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG)Avataris modified, I verified thatAvataris working as expected in all cases)QA Steps
Same as Tests above
Screenshots
Web
Mobile Web
Desktop
iOS
Android