-
Notifications
You must be signed in to change notification settings - Fork 3k
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
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 |
tests/ui/UnreadIndicatorsTest.js
Outdated
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again here, adding await
to each of the merge()
methods should allow this waitForPromisesToResolve()
to be removed.
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.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
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! 🔥 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
|
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.
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.
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'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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
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.
Wow, those tests are looking great now!
@@ -0,0 +1 @@ | |||
export default {}; |
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.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❤️ 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
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.
Looks great!
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 usingreportActionID
forreportAction_*
values keys)sequenceNumber
were being set toclientID
which made it impossible to mark a "pending" comment as unread. Instead we use a guessedsequenceNumber
for this. I suspect this may need to change in the future or depend onreportActionID
as well.type
field (Fixed)previousMessage
field 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 Issues
section aboveTests
sectionQA steps
sectiontoggleReport
and notonIconClick
)src/languages/*
filesSTYLE.md
) were followedAvatar
, I verified the components usingAvatar
are working as expected)/** comment above it */
displayName
propertythis
properly so there are no scoping issues (i.e. foronClick={this.submit}
the methodthis.submit
should be bound tothis
in the constructor)this
are necessary to be bound (i.e. avoidthis.submit = this.submit.bind(this);
ifthis.submit
is never passed to a component event handler likeonClick
)StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG
)Avatar
is modified, I verified thatAvatar
is 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 Issues
section aboveTests
sectionQA steps
sectiontoggleReport
and notonIconClick
).src/languages/*
filesSTYLE.md
) were followedAvatar
, I verified the components usingAvatar
have been tested & I retested again)/** comment above it */
displayName
propertythis
properly so there are no scoping issues (i.e. foronClick={this.submit}
the methodthis.submit
should be bound tothis
in the constructor)this
are necessary to be bound (i.e. avoidthis.submit = this.submit.bind(this);
ifthis.submit
is never passed to a component event handler likeonClick
)StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG
)Avatar
is modified, I verified thatAvatar
is working as expected in all cases)QA Steps
Same as Tests above
Screenshots
Web
Mobile Web
Desktop
iOS
Android