Skip to content

feat: Shift+Click Range Selection Not Supported in Multi-Select Lists#92155

Open
TaduJR wants to merge 24 commits into
Expensify:mainfrom
TaduJR:feat-New-Feature-Shift+Click-Range-Selection-Not-Supported-in-Multi-Select-Lists
Open

feat: Shift+Click Range Selection Not Supported in Multi-Select Lists#92155
TaduJR wants to merge 24 commits into
Expensify:mainfrom
TaduJR:feat-New-Feature-Shift+Click-Range-Selection-Not-Supported-in-Multi-Select-Lists

Conversation

@TaduJR
Copy link
Copy Markdown
Contributor

@TaduJR TaduJR commented May 31, 2026

Explanation of Change

This PR adds Excel-style shift+click range selection to every multi-select list in the app. Anywhere users see checkboxes next to rows — workspace settings, Spend search results, Insights groups, the in-report transaction list — they can now hold Shift and click a second row to select everything between the first click and the second. Shift+clicking again extends the range further, shrinks it back, or flips it across the original click — exactly how Excel, Gmail, Outlook, and Finder behave. Mobile selection (long-press to enter selection mode, then tap to add) is untouched, and Shift+Arrow keyboard extension is intentionally out of scope — Expensify Classic doesn't support it either.

Holding Cmd (or Ctrl) — additive range

Holding Cmd on Mac (or Ctrl on Windows/Linux) while shift+clicking adds the new range to the existing selection without deselecting the previous one. This matches Mac Finder, Excel, and Expensify Classic — useful for picking disjoint groups of rows in one pass. A subsequent plain Shift+Click replaces the last additive range, so the muscle memory works the same as in Excel.

What changed under the hood

A new hook — src/hooks/useShiftRangeSelection.ts — owns the logic. The session state (an Idle | Anchored | Ranging discriminated union) lives in a single useRef so plain-click anchor updates don't trigger render churn in the consumer; transitions are computed by a pure sessionReducer function and range computation by a pure computeShiftRange function. Each list passes its visible rows in and gets back a small set of methods to call from its click handlers:

  • when the user shift-clicks a row, the list calls the hook with the clicked row and the modifier state (shift, plus the platform additive key if held);
  • when the user plain-clicks a row (or moves focus with the arrow keys via useArrowKeyFocusManager's onFocusedIndexChange), the list tells the hook so the next shift+click anchors from the right place;
  • when the user hits Select All / Deselect All, the list tells the hook to reset.

The hook is the only place that knows the rules — anchor resolution, range computation, skipping headers and disabled rows, shrinking ranges, reversing direction, additive vs replacing — so every list behaves the same way. The session is explicit and deterministic: it lives between shift+clicks and ends only when the consumer tells the hook a non-shift interaction happened.

Pure helpers and types — the modifier-event reader, the primitive-key batch applier, a small farthest-end-from-anchor utility, and the Modifiers / ShiftRangeBatch types — live in src/libs/shiftRangeSelection/. The hook file holds only React state.

Where it shows up

Most workspace pages (Tags, Categories, Members, Taxes, Distance Rates, Per Diem, Report Fields, Expense Rules, Spend Rules → Card / Category, Room Members, Report Participants) get it by adding one prop to the shared BaseSelectionList component — onShiftRangeApply. Three lists with their own custom selection plumbing — the Spend search results (Expenses, Reports, and the Insights views like Top Categories and Top Merchants), the transaction list inside a single expense report (both flat and Group-by-Category / Tag), and the Workspace Expensify Card list — wire the hook directly with the same protocol.

Group headers

In any grouped list (Spend grouped by Category / Tag / Merchant / Card / Month / etc., and the in-report grouped view), shift-clicking a group header extends the range through the whole group, not just to the header. The hook receives the farthest loaded child of that group as the actual target so the range covers both edges of the group plus the gap to the anchor. Collapsed groups (where children haven't loaded yet) fall back to the existing "select all in this group" toggle.

Helpers

Two small helpers ship alongside the hook in @libs/shiftRangeSelection/ so each consumer can wire up in a couple of lines:

  • one for selection state stored as a list of primitive keys (string[] / number[]) — used by most pages;
  • one for reading the Shift key and the platform additive modifier off any event shape (React Native, RN-Web, DOM).

Fixed Issues

$ #90539
PROPOSAL: #90539 (comment)

Tests

Setup

  • A test workspace with at least 8 tags, 8 categories, and several taxes / distance rates / per diem rates.
  • A test expense report with at least 6 transactions across more than one category (so the in-report Group-by-Category layout shows 2+ groups).
  • A workspace whose Spend → Expenses results have at least 6 transactions.

A. Workspace lists — basic shift+click range

Use Workspaces → [your workspace] → Tags as the representative page. Repeat on Categories, Members, Taxes, Distance rates, Per diem, Report fields, Expense rules, Spend rules → Card / Category, Room members, Report participants.

  1. Left sidebar → Workspaces → click your test workspace → click Tags in the workspace sidebar.
  2. Click the checkbox of the 2nd tag.
  3. Hold Shift and click the checkbox of the 6th tag.
  4. Verify tags 2, 3, 4, 5, 6 are all checked.
  5. Without clicking anywhere else, hold Shift and click the checkbox of the 4th tag.
  6. Verify tags 5 and 6 become unchecked while 2, 3, 4 stay checked.
  7. Hold Shift and click the checkbox of the 1st tag.
  8. Verify tags 1, 2 are checked and 3, 4 become unchecked.

B. Workspace lists — deselect then shift+click (anchor stays in range)

  1. On the Tags page, click the checkbox of the 3rd tag (it becomes checked).
  2. Click the same checkbox again (it becomes unchecked — list is now empty).
  3. Hold Shift and click the checkbox of the 7th tag.
  4. Verify tags 3, 4, 5, 6, 7 are all checked. Tag 3 must be included in the selection.

C. Workspace lists — Select All then shift+click

  1. On the Tags page, click the checkbox of the 1st tag.
  2. Hold Shift and click the checkbox of the 5th tag (tags 1–5 are checked).
  3. Click the Select all tags header checkbox at the top of the list.
  4. The checkbox may first deselect all tags (this is the toggle's "indeterminate → empty" step). If so, click it once more so every tag is checked.
  5. Verify every tag in the list is now checked.
  6. Hold Shift and click the checkbox of the 3rd tag.
  7. Verify all tags remain checked — no tag (especially tags 4 or 5) should silently become unchecked.

D. Spend → Expenses (flat list)

  1. Left sidebar → Spend (the icon rail). The Spend secondary sidebar appears.
  2. In the Spend secondary sidebar under Expense reports, click Expenses.
  3. Click the checkbox of the 1st transaction in the table.
  4. Hold Shift and click the checkbox of a transaction further down (e.g. the 4th).
  5. Verify every transaction between them is checked.
  6. Hold Shift and click the checkbox of a transaction above the original click (e.g. the 2nd).
  7. Verify the range collapses — only rows from the new top through the original anchor stay checked.

E. Spend → Reports — flat list + opened report

  1. Left sidebar → Spend → in the Spend sidebar click Reports (under "Expense reports").
  2. The Reports list appears — each report is a single row (no inline expand arrow on the row).
  3. Click the checkbox of the 1st report.
  4. Hold Shift and click the checkbox of the 3rd report.
  5. Verify reports 1, 2, 3 are all checked.
  6. Hold Shift and click the checkbox of the 1st report (back where you started).
  7. Verify only the 1st report stays checked.
  8. Click the title or row body of a report (not the checkbox) to open it. The report's detail page loads with the transaction list on the left and a chat/comments panel on the right.
  9. Click the Back arrow in the top-left header to return to the Reports list. Verify your previous selection (just the 1st report) is still in place.

F. Opened expense report — in-report transaction list

  1. From Spend → Reports, click a report row that contains several transactions across more than one category.
  2. At the top of the transaction list, verify the layout dropdown reads Group by: Category. Transactions are grouped with a header row per category (e.g. "Advertising", "Benefits"). Each header has its own checkbox.
  3. Click the checkbox of the 1st child transaction under the first group.
  4. Hold Shift and click the checkbox of a child transaction under a different group below.
  5. Verify every transaction in between — across all intermediate groups — is checked. Each group whose children are fully selected shows its header checkbox as checked too.
  6. Click that first child once more to deselect it; click it again to re-set it as the anchor.
  7. Hold Shift and click the group header checkbox of a different group below (e.g. the 3rd group). Its aria-label reads "Select all expenses in [Category]".
  8. Verify every transaction between the anchor and the end of that group is checked. The click must register on the first press — there should be no double-click required and no text should be highlighted anywhere on the page.
  9. Change the layout dropdown to Group by: Tag and repeat steps 6–8 against the tag groups.

G. Spend → Insights → Top categories (also Top merchants)

  1. Left sidebar → Spend → in the Spend sidebar under Insights, click Top categories. The page opens with a bar chart by default.
  2. Click the Display button at the top-right of the page. A side panel appears with options: Sort by, Group by, Group currency, View, Limit results, Edit columns.
  3. Click the View row. A submenu shows Table / Bar / Line / Pie.
  4. Click Table, then click the Apply button at the bottom of the panel.
  5. The page now shows a list of category rows (Advertising, Benefits, Car, …), each with a checkbox and an Expand chevron on the far right.
  6. Click the Expand chevron on the Advertising row to expand it. Repeat for at least one other category (e.g. Benefits).
  7. Click the checkbox of the 1st child transaction under Advertising.
  8. Hold Shift and click the checkbox of the last child transaction in Advertising.
  9. Verify every Advertising child between the two is checked.
  10. Hold Shift and click the Benefits header checkbox.
  11. Verify Benefits' header checkbox becomes checked and every Benefits child becomes checked. Any collapsed category below (e.g. Car, Interest) stays unchecked.
  12. Repeat steps 1–11 on Top merchants (same Insights group, same flow).

H. Workspace Expensify Card list

  1. Left sidebar → Workspaces → click your test workspace → in the workspace sidebar click Expensify Card (singular).
  2. The card list appears with at least 4 rows. Each row has a checkbox in the leftmost column.
  3. Click the checkbox of the 1st card.
  4. Hold Shift and click the checkbox of the 3rd card.
  5. Verify every card between them (cards 1, 2, 3) is checked.
  6. Click the header checkbox at the top of the table (its aria-label reads Select all items). If some cards were already selected, the first click deselects them all — click again to select all cards.
  7. Verify every card row is now checked.
  8. Click the header checkbox again to deselect everything.
  9. Hold Shift and click the checkbox of the 3rd card.
  10. Verify only the 3rd card is checked — no leftover selection state from earlier steps.

I. Holding Cmd (or Ctrl) — additive multi-range selection

Verifies Shift+Cmd (Mac) / Shift+Ctrl (Windows/Linux). Best done on the Tags page where rows are uniform; repeat on Spend → Expenses to confirm the search list path too.

  1. On the Tags page, click the checkbox of the 1st tag.
  2. Hold Shift and click the checkbox of the 3rd tag. Tags 1–3 become checked.
  3. Click the checkbox of the 6th tag (plain click — sets a new anchor for the next shift+click).
  4. Hold Shift + Cmd (Mac) or Shift + Ctrl (Windows/Linux) and click the checkbox of the 8th tag.
  5. Verify tags 1, 2, 3 are still checked (the original range survives) and tags 6, 7, 8 are now also checked. You should have two disjoint selected ranges.
  6. Without clicking anywhere else, hold Shift alone (no Cmd/Ctrl) and click the checkbox of the 7th tag.
  7. Verify tags 1–3 stay checked, tags 6, 7 stay checked, tag 8 becomes unchecked. (Plain Shift+Click replaces the most recent range without touching the additive one.)
  8. Repeat steps 1–7 on Spend → Expenses to confirm the search list path.
  • Verify that no errors appear in the JS console

Offline tests

Same as tests

QA Steps

// TODO: These must be filled out, or the issue title must include "[No QA]."
Same as tests

  • Verify that no errors appear in the JS console

PR Author Checklist

  • I linked the correct issue in the ### Fixed Issues section above
  • I wrote clear testing steps that cover the changes made in this PR
    • I added steps for local testing in the Tests section
    • I added steps for the expected offline behavior in the Offline steps section
    • I added steps for Staging and/or Production testing in the QA steps section
    • I added steps to cover failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
    • I tested this PR with a High Traffic account against the staging or production API to ensure there are no regressions (e.g. long loading states that impact usability).
  • I included screenshots or videos for tests on all platforms
  • I ran the tests on all platforms & verified they passed on:
    • Android: Native
    • Android: mWeb Chrome
    • iOS: Native
    • iOS: mWeb Safari
    • MacOS: Chrome / Safari
    • MacOS: Desktop
  • I verified there are no console errors (if there's a console error not related to the PR, report it or open an issue for it to be fixed)
  • I verified there are no new alerts related to the canBeMissing param for useOnyx
  • I followed proper code patterns (see Reviewing the code)
    • I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick)
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
    • I verified any copy / text shown in the product is localized by adding it to src/languages/* files and using the translation method
      • If any non-english text was added/modified, I used JaimeGPT to get English > Spanish translation. I then posted it in #expensify-open-source and it was approved by an internal Expensify engineer. Link to Slack message:
    • I verified all numbers, amounts, dates and phone numbers shown in the product are using the localization methods
    • I verified any copy / text that was added to the app is grammatically correct in English. It adheres to proper capitalization guidelines (note: only the first word of header/labels should be capitalized), and is either coming verbatim from figma or has been approved by marketing (in order to get marketing approval, ask the Bug Zero team member to add the Waiting for copy label to the issue)
    • I verified proper file naming conventions were followed for any new files or renamed files. All non-platform specific files are named after what they export and are not named "index.js". All platform-specific files are named for the platform the code supports as outlined in the README.
    • I verified the JSDocs style guidelines (in STYLE.md) were followed
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I followed the guidelines as stated in the Review Guidelines
  • I tested other components that can be impacted by my changes (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar are working as expected)
  • I verified all code is DRY (the PR doesn't include any logic written more than once, with the exception of tests)
  • I verified any variables that can be defined as constants (ie. in CONST.ts or at the top of the file that uses the constant) are defined as such
  • I verified that if a function's arguments changed that all usages have also been updated correctly
  • If any new file was added I verified that:
    • The file has a description of what it does and/or why is needed at the top of the file if the code is not self explanatory
  • If a new CSS style is added I verified that:
    • A similar style doesn't already exist
    • The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))
  • If new assets were added or existing ones were modified, I verified that:
    • The assets are optimized and compressed (for SVG files, run npm run compress-svg)
    • The assets load correctly across all supported platforms.
  • If the PR modifies code that runs when editing or sending messages, I tested and verified there is no unexpected behavior for all supported markdown - URLs, single line code, code blocks, quotes, headings, bold, strikethrough, and italic.
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
  • If the PR modifies a component or page that can be accessed by a direct deeplink, I verified that the code functions as expected when the deeplink is used - from a logged in and logged out account.
  • If the PR modifies the UI (e.g. new buttons, new UI components, changing the padding/spacing/sizing, moving components, etc) or modifies the form input styles:
    • I verified that all the inputs inside a form are aligned with each other.
    • I added Design label and/or tagged @Expensify/design so the design team can review the changes.
  • If a new page is added, I verified it's using the ScrollView component to make it scrollable when more elements are added to the page.
  • I added unit tests for any new feature or bug fix in this PR to help automatically prevent regressions in this user flow.
  • If the main branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to the Test steps.

Screenshots/Videos

Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari
Macbook-Chrome.mp4

@TaduJR TaduJR requested review from a team as code owners May 31, 2026 20:20
@melvin-bot
Copy link
Copy Markdown

melvin-bot Bot commented May 31, 2026

@QichenZhu Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button]

@melvin-bot melvin-bot Bot removed request for a team May 31, 2026 20:20
@TaduJR TaduJR changed the title Feat new feature shift+click range selection not supported in multi select lists feat: New Feature : Shift+Click Range Selection Not Supported in Multi-Select Lists May 31, 2026
@TaduJR TaduJR changed the title feat: New Feature : Shift+Click Range Selection Not Supported in Multi-Select Lists feat: Shift+Click Range Selection Not Supported in Multi-Select Lists May 31, 2026
@TaduJR TaduJR marked this pull request as draft May 31, 2026 20:31
@TaduJR
Copy link
Copy Markdown
Contributor Author

TaduJR commented May 31, 2026

@codex review

@codecov
Copy link
Copy Markdown

codecov Bot commented May 31, 2026

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Delightful!

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@TaduJR
Copy link
Copy Markdown
Contributor Author

TaduJR commented May 31, 2026

D. Shift+Arrow keyboard nav (desktop with physical keyboard)

  1. Navigate to Workspaces → [your workspace] → Tags.
  2. Wait for the tag list to render. Do not click any tag yet (so nothing is selected).
  3. Click the checkbox of the 3rd tag once. Verify tag 3 is checked.
  4. Click the same checkbox again. Verify tag 3 is unchecked (list is empty again).
  5. Click the checkbox of the 3rd tag once more (so tag 3 is checked and is the anchor).
  6. Without clicking anywhere else, press and hold Shift, then press ArrowDown once. Release Shift.

Expected
Tag 3 stays checked, and tag 4 (the next row down) also becomes checked.

@QichenZhu

We have upstream bug on react-native-key-command for the above case. Should we remove it for now and make a second PR, or handle it first on upstream?

@QichenZhu
Copy link
Copy Markdown
Contributor

QichenZhu commented Jun 1, 2026

@TaduJR I'm not sure this is relevant to the original issue, which only mentions Shift+Click. I strongly suggest writing the steps yourself to reflect the actual testing flow you did, as AI tends to generate excessive steps in seconds but testers need hours to execute them, which is not practical.

@TaduJR
Copy link
Copy Markdown
Contributor Author

TaduJR commented Jun 1, 2026

@TaduJR I'm not sure this is relevant to the original issue, which only mentions Shift+Click. I strongly suggest writing the steps yourself to reflect the actual testing flow you did, as AI tends to generate excessive steps in seconds but testers need hours to execute them, which is not practical.

@QichenZhu

Hmm I validate the test steps and use AI to cover cases as much as possible so we will not skip edge cases or introduce regressions, but I feel you on the long steps.

But the case I flagged seems to be a valid one and might be flagged during QA because even on a folder structure macOS there is support for Shift + Arrow Down and react-native-key-command is not capturing it.

That's why I raised the question.

@QichenZhu
Copy link
Copy Markdown
Contributor

@TaduJR could you check with the internal team? This expands the scope.

@TaduJR
Copy link
Copy Markdown
Contributor Author

TaduJR commented Jun 1, 2026

@TaduJR could you check with the internal team? This expands the scope.

Sure, Thanks!

@twisterdotcom
Copy link
Copy Markdown
Contributor

I don't think we need to account for shift+arrow down. We don't support it on Expensify Classic. There is no expectation it will be supported here based on that.

@TaduJR
Copy link
Copy Markdown
Contributor Author

TaduJR commented Jun 2, 2026

Just to mention. Also about Shift and Cmd usage to split select

Screen.Recording.2026-06-02.at.3.00.11.PM.mov

@TaduJR
Copy link
Copy Markdown
Contributor Author

TaduJR commented Jun 2, 2026

I don't think we need to account for shift+arrow down. We don't support it on Expensify Classic. There is no expectation it will be supported here based on that.

Thanks @twisterdotcom

Just to mention. Also about Shift and Cmd usage to split select

In that case i suppose this is not supported also in OD right?

TaduJR added 2 commits June 2, 2026 15:09
…ature-Shift+Click-Range-Selection-Not-Supported-in-Multi-Select-Lists

# Conflicts:
#	src/components/Search/index.tsx
@twisterdotcom
Copy link
Copy Markdown
Contributor

Wow, we do support shift+cmd select in Classic, so... if we can support that here too, that would be ace.

@TaduJR
Copy link
Copy Markdown
Contributor Author

TaduJR commented Jun 2, 2026

Wow, we do support shift+cmd select in Classic, so... if we can support that here too, that would be ace.

Nice. I will include it. This is why I was testing for various cases. I will update the tests.

Heads up @QichenZhu

Test Case might grow even more.

Thanks 🙏!

@TaduJR
Copy link
Copy Markdown
Contributor Author

TaduJR commented Jun 3, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d5d1838f1e

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/components/Search/index.tsx
@TaduJR
Copy link
Copy Markdown
Contributor Author

TaduJR commented Jun 3, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3a4ae64a0e

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/hooks/useShiftRangeSelection.ts Outdated
@TaduJR
Copy link
Copy Markdown
Contributor Author

TaduJR commented Jun 3, 2026

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@TaduJR TaduJR marked this pull request as ready for review June 3, 2026 08:02
@QichenZhu
Copy link
Copy Markdown
Contributor

Hmm I validate the test steps and use AI to cover cases as much as possible so we will not skip edge cases or introduce regressions, but I feel you on the long steps.

@TaduJR agree it's good to test thoroughly, but here the AI focused on quantity rather than quality. For example, this PR has some refactoring so we want to make sure we won't introduce regressions on mobile platforms, but the test steps don't cover that.

…ature-Shift+Click-Range-Selection-Not-Supported-in-Multi-Select-Lists
@TaduJR
Copy link
Copy Markdown
Contributor Author

TaduJR commented Jun 3, 2026

@QichenZhu

@TaduJR agree it's good to test thoroughly, but here the AI focused on quantity rather than quality.

To get our idea fully. All the test cases covered are unique cases of the feature right?, so by quality means is it uniqueness or reduction of verbosity to make it shallow?

For example, this PR has some refactoring so we want to make sure we won't introduce regressions on mobile platforms, but the test steps don't cover that.

I deliberately removed the mobile test cases after your concern on the steps being long and since it was not related to the core feature and after testing locally. Should I bring it back?

…ature-Shift+Click-Range-Selection-Not-Supported-in-Multi-Select-Lists
Copy link
Copy Markdown
Contributor

@joekaufmanexpensify joekaufmanexpensify left a comment

Choose a reason for hiding this comment

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

Nice improvement 👍

@QichenZhu
Copy link
Copy Markdown
Contributor

QichenZhu commented Jun 3, 2026

@TaduJR agree it's good to test thoroughly, but here the AI focused on quantity rather than quality.

To get our idea fully. All the test cases covered are unique cases of the feature right?, so by quality means is it uniqueness or reduction of verbosity to make it shallow?

@TaduJR what I mean by quality is focusing on what matters: the risky scenarios that help catch bugs. AI doesn't know what's actually important in our context, so it tends to cover everything evenly. But our energy and attention are limited, and working through many routine steps can desensitize us to the real risks.

For example, this PR has some refactoring so we want to make sure we won't introduce regressions on mobile platforms, but the test steps don't cover that.

I deliberately removed the mobile test cases after your concern on the steps being long and since it was not related to the core feature and after testing locally. Should I bring it back?

Thanks for testing it locally, I'll do it too. Could you update the steps to reflect what you did and were recorded in your video and remove the rest?

@QichenZhu
Copy link
Copy Markdown
Contributor

@TaduJR gentle bump

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.

5 participants