How to Write Test Cases for Infinite Scroll (With Examples)
How to Write Test Cases for Infinite Scroll (With Examples)
How to Write Test Cases for Infinite Scroll (With Examples)
Infinite scroll is a UI pattern that loads content dynamically as the user scrolls toward the bottom of a list or feed. Testing it requires verifying that data fetches correctly, rendering stays stable, interactions remain usable, and failure modes are handled gracefully. This guide walks through a complete test‑case workflow: defining test‑case anatomy, building a concrete matrix of 20+ examples, prioritizing them, linking to requirements, and augmenting manual designs with autonomous exploration. Every section contains actionable steps, tables, or code snippets you can copy into your test repository today.
Understanding Infinite Scroll Behavior
Before writing test cases, clarify what the infinite‑scroll component does under the hood. Most implementations consist of three collaborating parts:
- Viewport detector – a scroll listener (often
IntersectionObserveror a scroll‑event handler) that fires when the user nears the bottom threshold. - Data loader – an asynchronous request (REST, GraphQL, WebSocket) that asks the backend for the next page of items, usually identified by a cursor, offset, or timestamp.
- Renderer – a function that appends the newly received items to the DOM or RecyclerView, updates internal state, and may adjust placeholders or loading spinners.
Key behavioral contracts to test:
- Fetch trigger – the loader starts exactly once when the scroll position crosses the configured offset (e.g., 200 px from the bottom).
- Idempotency – rapid successive scrolls do not launch duplicate requests unless the previous request has completed.
- State consistency – the list length matches the sum of all successfully fetched pages; no items are lost or duplicated.
- UI feedback – a loading indicator appears while a request is pending and disappears on success or error.
- Error handling – on network failure or HTTP 5xx, the component shows an error state, allows retry, and does not corrupt existing items.
- Termination condition – when the backend signals “no more data” (empty response or a flag), scrolling stops triggering loads and a “end‑of‑list” cue appears.
- Accessibility – newly added items receive appropriate ARIA roles/labels and are reachable via keyboard or screen‑reader navigation.
- Performance – the time between scroll trigger and UI update stays within a perceivable budget (commonly < 200 ms on mid‑tier devices).
Understanding these contracts lets you map each test case to a specific verification point, avoiding overlap and ensuring high signal.
Anatomy of a Good Test Case for Infinite Scroll
A test case that survives review and automation follows a strict structure:
| Element | Purpose | Example for Infinite Scroll |
|---|---|---|
| ID | Unique identifier (e.g., IS-001) | IS-001 |
| Title | Concise description of what is verified | “Initial load shows first page and loading spinner appears on scroll near bottom” |
| Preconditions | Required state before execution | “App is launched, user is logged in, network is stable, backend returns page 1 with 20 items” |
| Steps | Ordered actions the tester or script performs | 1. Wait for list to render 2. Scroll down until the last item is within 150 px of viewport bottom 3. Observe network request 4. Verify UI |
| Expected Result | Observable outcome that determines PASS/FAIL | “A second network request for page 2 is issued, a spinner shows while waiting, and after response the list contains 40 items with no duplicates” |
| Test Type | Functional, negative, performance, accessibility, etc. | Functional |
| Priority | P0 (must), P1 (should), P2 (could) | P0 |
| Traceability | Link to requirement or user story | REQ-INF-03: Load next page on scroll |
| Automation Flag | Indicates if case is scripted, manual, or hybrid | Automated (Playwright) |
| Notes | Any special setup, flakiness mitigation, or data‑seed notes | Use mock server that delays page 2 by 300 ms to observe spinner |
Keep each element explicit; vague preconditions like “app is ready” lead to irreproducible results. When you write the steps, phrase them as imperative commands that a test runner can follow without interpretation (e.g., “swipe up 800 px” rather than “scroll a bit”).
Positive Test Cases (Normal Operation)
Positive cases confirm the happy path: data loads, UI updates, and the user can continue scrolling indefinitely. Below is a matrix of 12 core positive cases. Each row follows the anatomy defined above.
| ID | Title | Preconditions | Steps | Expected Result | Priority | Traceability |
|---|---|---|---|---|---|---|
| IS-001 | Initial load renders first page and shows loading indicator on approach | App launched, authenticated, mock API returns page 1 (20 items) with hasMore:true | 1. Wait for list to render 2. Scroll down until last item is within 120 px of viewport bottom 3. Observe network tab | A GET request for page 2 is triggered, a spinner appears over the list, and after 300 ms the list expands to 40 items | P0 | REQ-INF-01 |
| IS-002 | Subsequent scrolls trigger correct pagination offsets | Precondition: page 1 and page 2 already loaded (40 items) | 1. Scroll until near bottom again 2. Check request URL/query | Request for page 3 with correct cursor/offset is sent, no duplicate request for page 2 | P0 | REQ-INF-02 |
| IS-003 | List maintains item order and uniqueness after multiple loads | Precondition: three pages loaded (60 items) each with unique IDs 1‑60 | 1. Scroll to bottom twice more 2. Collect all item IDs from DOM | IDs 1‑80 appear exactly once, in ascending order | P0 | REQ-INF-03 |
| IS-004 | Loading spinner disappears after successful fetch | Precondition: network latency simulated 500 ms for page 3 | 1. Trigger load for page 3 2. Observe spinner visibility | Spinner is visible from request start until DOM update completes, then hidden | P1 | REQ-UX-05 |
| IS-005 | Placeholder rows are replaced with real data without layout shift | Precondition: server returns items with varying heights | 1. Enable placeholder shimmer 2. Scroll to trigger load 3. Measure viewport scroll position before and after | Scroll position change < 5 px (no jump), placeholders swapped with actual content | P1 | REQ-UX-06 |
| IS-006 | End‑of‑list signal stops further loads | Precondition: mock API returns hasMore:false on page 5 | 1. Scroll until page 5 loads 2. Continue scrolling to bottom | No further network requests, a “No more content” banner appears | P0 | REQ-INF-04 |
| IS-007 | Scrolling back up does not reload already‑fetched pages | Precondition: pages 1‑4 loaded | 1. Scroll to bottom to load page 4 2. Swipe up fully to top 3. Scroll down again | No new requests for pages 1‑4; only page 5 request if applicable | P1 | REQ-PERF-01 |
| IS-008 | Rapid successive scrolls (fling) trigger at most one request per viewport crossing | Precondition: network delay 400 ms | 1. Perform a fast fling that crosses threshold twice within 200 ms 2. Count network calls | Exactly one request for the next page is made | P1 | REQ-PERF-02 |
| IS-009 | Scrolling works with keyboard (Page Down) as well as touch | Precondition: focusable list container | 1. Press Page Down repeatedly 2. Observe network | Each Page Down that reaches the threshold triggers a load, same as touch | P1 | REQ-ACC-01 |
| IS-010 | Screen‑reader announces newly added items | Precondition: TalkBack/VoiceOver enabled | 1. Trigger load for next page 2. Listen to announcements | Screen reader reads “20 new items loaded” or reads each new item as it appears | P1 | REQ-ACC-02 |
| IS-011 | List retains scroll position after orientation change | Precondition: user scrolled halfway through page 3 | 1. Rotate device to landscape 2. Return to portrait | Scroll offset restored, same visible items, no extra request | P1 | REQ-UX-07 |
| IS-012 | Infinite scroll works under weak 3G simulation | Precondition: network throttled to 1.6 Mbps downlink, 400 ms RTT | 1. Scroll to trigger load 2. Measure time from request start to UI update | Update completes within 2 seconds, spinner shown throughout | P2 | REQ-PERF-03 |
These twelve cases cover the essential functional flow, ordering, UI feedback, termination, accessibility, and basic performance under normal conditions.
Negative and Error Handling Test Cases
Infinite scroll must degrade gracefully when the backend fails, returns malformed data, or the device loses connectivity. Negative cases verify that the UI stays usable and that no corrupt state leaks.
| ID | Title | Preconditions | Steps | Expected Result | Priority | Traceability |
|---|---|---|---|---|---|---|
| ISN-001 | Network timeout shows error banner and allows retry | Mock API delays page 2 beyond 10 s timeout | 1. Scroll to trigger page 2 load 2. Wait for timeout | Error banner appears with “Retry” button, existing items remain unchanged, spinner hidden | P0 | REQ-ERR-01 |
| ISN-002 | HTTP 500 response displays error state without crashing | Mock API returns 500 Internal Server Error for page 2 | 1. Trigger load for page 2 2. Observe UI | Error banner shown, list still displays page 1 items, no JavaScript exception in console | P0 | REQ-ERR-02 |
| ISN-003 | Malformed JSON (missing required fields) is handled safely | Mock API returns page 2 with items lacking id | 1. Trigger load 2. Observe rendering | Items with missing data are skipped or shown as placeholders, no crash, console logs warning | P1 | REQ-ERR-03 |
| ISN-004 | Empty response (zero items) with hasMore:true does not cause infinite loop | Mock API returns empty array but hasMore:true | 1. Trigger load 2. Observe behavior | No new rows added, spinner hidden, a temporary “Loading…” toast may appear, subsequent scrolls again trigger load (no busy‑loop) | P1 | REQ-ERR-04 |
| ISN-005 | Sudden loss of network mid‑fetch shows offline state | Mock API disconnects after request headers sent | 1. Start scroll load 2. Drop network 3. Wait | Offline banner appears, spinner hidden, user can retry when connectivity returns | P0 | REQ-ERR-06 |
| ISN-006 | Rapid error bursts (e.g., 5xx then timeout) do not stack multiple banners | Mock API alternates 500 and timeout | 1. Trigger three rapid loads causing errors 2. Observe UI | Only the most recent error banner is visible, no duplicate banners | P1 | REQ-UX-08 |
| ISN-007 | User taps retry after error, scrolling again triggers a fresh request | Precondition: error banner visible from ISN-001 | 1. Tap “Retry” button 2. Scroll to bottom again | New request issued, previous error cleared on success | P1 | REQ-ERR-07 |
| ISN-008 | Accessibility live region updates when error appears | Precondition: screen reader active | 1. Cause network error 2. Listen to announcements | Live region announces “Error loading more items. Tap to retry.” | P1 | REQ-ACC-03 |
| ISN-009 | Error state persists across configuration change | Precondition: error banner showing | 1. Rotate device 2. Return to original orientation | Error banner still visible, same message, retry still functional | P1 | REQ-UX-09 |
| ISN-010 | Server returns duplicate items; UI deduplicates | Mock API returns page 2 with same IDs as page 1 | 1. Trigger load 2. Check list | No duplicate IDs appear; either duplicates are filtered out or a warning is logged | P1 | REQ-DATA-01 |
These ten negative cases ensure resilience against flaky networks, bad payloads, and edge‑case server behaviors. Prioritize those that could lead to data loss or crashes (P0) and those that affect user trust (P1).
Edge and Boundary Conditions
Edge cases push the component to its limits: very large lists, extremely fast/slow scroll, memory pressure, and unusual input devices. They often surface only in production after prolonged use.
| ID | Title | Preconditions | Steps | Expected Result | Priority | Traceability |
|---|---|---|---|---|---|---|
| ISE-001 | Very first scroll (list empty) triggers load if threshold met | Precondition: list rendered with zero items, placeholder shows “Loading…” | 1. Scroll down immediately (even 10 px) | Request for page 1 fires, placeholder replaced with real items | P0 | REQ-INF-05 |
| ISE-002 | Scrolling past the bottom when hasMore:false shows no spinner | Precondition: end‑of‑list reached | 1. Attempt to fling further down 2. Observe UI | No spinner, no request, “End of list” stays visible | P1 | REQ-UX-10 |
| ISE-003 | List with item heights exceeding viewport (e.g., full‑screen cards) still triggers correctly | Precondition: each item = 100 vh | 1. Scroll until one card fully visible 2. Continue slight scroll | Load triggers when the last card’s bottom nears threshold, no missed triggers | P1 | REQ-UX-11 |
| ISE-004 | Rapid orientation changes during pending load do not cause duplicate requests | Precondition: network latency 800 ms for page 3 | 1. Trigger load 2. Rotate landscape → portrait → landscape quickly 3. Wait for response | Only one request for page 3 is made, UI updates once | P1 | REQ-PERF-04 |
| ISE-005 | Low memory device: app does not OOM after scrolling 200 pages | Precondition: emulator with 512 MB RAM, each item ~10 KB | 1. Scroll continuously for 5 minutes 2. Monitor memory | Memory growth plateaus (due to view recycling), no crash | P0 | REQ-RES-01 |
| ISE-006 | Scrolling with a connected mouse wheel on web triggers loads | Precondition: desktop Chrome, focus on list | 1. Rotate mouse wheel downwards until threshold 2. Observe network | Request fired same as touch | P1 | REQ-ACC-04 |
| ISE-007 | Touch start outside list (e.g., on header) still propagates to scroll listener | Precondition: fixed header above list | 1. Place finger on header, drag down into list area 2. Continue to threshold | Load triggers as if started inside list | P1 | REQ-UX-12 |
| ISE-008 | Programmatic scroll (e.g., scrollTo) triggers load if it crosses threshold | Precondition: list at top | 1. Execute window.scrollTo(0, document.body.height - 300)2. Observe | Load fires, consistent with user‑initiated scroll | P1 | REQ-API-01 |
| ISE-009 | Scrolling while a modal dialog is open does not trigger background loads | Precondition: modal overlay covering list | 1. Open modal 2. Attempt to scroll behind it (gesture blocked) 3. Close modal 4. Scroll to threshold | No request while modal open; after dismiss, normal behavior resumes | P1 | REQ-MODAL-01 |
| ISE-010 | List with sticky header/footer maintains correct threshold calculation | Precondition: 56 px header, 44 px footer | 1. Scroll until last item is within threshold of viewport (excluding footer) 2. Observe | Load fires at correct visual point, not obscured by fixed elements | P1 | REQ-LAYOUT-02 |
These ten edge cases address scenarios that are easy to overlook but can cause silent failures, excessive battery drain, or crashes in the wild. Mark those that could lead to OOM or infinite loops as P0.
Performance and Load Considerations
Performance testing for infinite scroll goes beyond measuring a single request; it looks at frame rate, jank, memory, and network utilization over extended sessions. Use profiling tools (Android Studio Profiler, Chrome DevTools, Instruments) alongside automated scripts.
Performance Test Matrix
| ID | Title | Preconditions | Steps | Metrics | Acceptance Threshold | Priority |
|---|---|---|---|---|---|---|
| ISP-001 | Average frame time stays under 16 ms during scroll with loading | Device Pixel 4, API 33, 60 fps target | 1. Record timeline while scrolling continuously for 30 s 2. Capture frame timestamps | 95 % of frames ≤ 16 ms | ≤ 2 % jank frames | P0 |
| ISP-002 | Memory growth per 100 items loaded stays below 2 MB | Android emulator 2 GB RAM | 1. Load 20 pages (≈4000 items) 2. Take heap snapshot before/after | Delta ≤ 2 MB | ≤ 2 MB | P0 |
| ISP-003 | Network utilization does not exceed 50 % of available bandwidth during idle scroll | Wi‑Fi 20 Mbps | 1. Throttle to 5 Mbps 2. Scroll slowly (no new loads) 3. Monitor TX/RX | Idle traffic ≤ 250 kbps | ≤ 500 kbps | P1 |
| ISP-004 | Time from scroll threshold to first visible new item (TTI) < 300 ms on 3G | Network throttled to 1.6 Mbps downlink, 400 ms RTT | 1. Trigger load 2. Measure from scroll event to DOM insertion of first new item | TTI ≤ 300 ms | ≤ 300 ms | P1 |
| ISP-005 | Battery drain per hour of continuous scrolling < 2 % on mid‑tier device | Nexus 5X, 3000 mAh battery | 1. Scroll continuously for 1 h 2. Measure battery delta | ≤ 2 % | ≤ 2 % | P2 |
| ISP-006 | CPU usage during placeholder shimmer animation < 15 % | Same device as ISP-001 | 1. Enable shimmer 2. Scroll idle (no loads) 3. Sample CPU | ≤ 15 % average | ≤ 15 % | P2 |
| ISP-007 | Scrolling with accessibility features enabled (large text, high contrast) does not increase TTI > 50 % | Font scale 200 %, contrast enabled | 1. Repeat ISP-004 with accessibility on 2. Compare TTI | ΔTTI ≤ 150 ms | ≤ 150 ms | P1 |
| ISP-008 | Concurrent infinite scroll instances (e.g., two tabs) do not interfere | Web app with two independent feeds | 1. Open two tabs, each with scroll 2. Scroll both alternately 3. Verify each loads correct page | No cross‑talk, each maintains its own offset | No cross‑talk | P1 |
| ISP-009 | Long session (4 h) does not cause leak in scroll listener registration | Automated script | 1. Run scroll loop for 4 h 2. Check that only one scroll listener remains active | Listener count = 1 | No listener leak | P0 |
| ISP-010 | Low‑end device (Snapdragon 450) maintains ≥ 30 fps during scroll with image loading | Low‑end Android phone | 1. Scroll with image‑heavy items (300 KB each) 2. Capture FPS | Average FPS ≥ 30 | ≥ 30 fps | P0 |
These ten performance cases give you a quantitative baseline. Automate them using a test runner that can capture metrics (e.g., playwright trace, adb shell dumpsys gfxinfo, or ios, or Lighthouse CI). Record results in a dashboard to detect regressions early.
Prioritization and Traceability to Requirements
A test suite must align with business value. Map each test case to a requirement identifier and assign a priority based on risk, user impact, and failure cost.
Requirement Traceability Table
| Requirement ID | Description | Linked Test Cases (ID) | Priority Derivation | ||
|---|---|---|---|---|---|
| REQ-INF-01 | Load next page when user approaches bottom | IS-001, IS-002, IS-003, IS-007, IS-008, IS-009, IS-010, IS-011, IS-012 | P0 – core functionality | ||
| REQ-INF-02 | Prevent duplicate requests during rapid scroll | IS-002, IS-008, ISN-006 | P0 – avoids wasted bandwidth | ||
| REQ-INF-03 | Show loading indicator while fetching | IS-004, IS-005, ISN-001, ISN-002 | P1 – UX feedback | ||
| REQ-INF-04 | Display end‑of‑list message when no more data | IS-006, ISE-002 | P0 – clear termination | ||
| REQ-ERR-01 | Gracefully handle network timeouts | ISN-001, ISN-005 | P0 – prevents broken UI | ||
| REQ-ERR-02 | Handle HTTP error codes without crash | ISN-002, ISN-006 | P0 – stability | ||
| REQ-ERR-03 | Recover from malformed payloads | ISN-003, ISN-004 | P1 – data integrity | ||
| REQ-UX-05 | Spinner hides on success/error | IS-004, ISN-001, ISN-002 | P1 – visual consistency | ||
| REQ-UX-06 | No layout jump when placeholders replace | IS-005, ISE-003 | P1 – visual stability | ||
| REQ-ACC-01 | Keyboard navigation triggers loads | IS-009 | P1 – accessibility | ||
| REQ-ACC-02 | Screen reader announces new items | IS-010, ISN-008 | P1 – | IS-010, ISN-008 | P1 – accessibility |
| REQ-ACC-04 | Mouse wheel works | ISE-006 | P1 – accessibility | ||
| REQ-PERF-01 | No reload of already‑fetched items on scroll up | IS-007 | P1 – efficiency | ||
| REQ-PERF-02 | Jank < 2 % during scroll | ISP-001, ISP-004, ISP-007 | P0 – perceived performance | ||
| REQ-PERF-03 | Memory bounded | ISP-002, ISE-005 | P0 – resource safety | ||
| REQ-RES-01 | No OOM after long session | ISE-005, ISP-009 | P0 – stability | ||
| REQ-MODAL-01 | Modal blocks background scroll | ISE-009 | P1 – interaction correctness | ||
| REQ-LAYOUT-02 | Sticky header/footer considered in threshold | ISE-010 | P1 – layout correctness |
When you maintain this table, you can generate a coverage report (e.g., using pytest markers or JUnit tags) that shows what percentage of requirements are exercised by your automated suite. Aim for ≥ 90 % requirement coverage before marking a feature as “ready for release.”
Combining Manual Test Cases with Autonomous Exploration (SUSA)
Manual test cases give you deterministic verification of known scenarios. Autonomous exploration complements them by exercising the app in ways a human might not think of, uncovering hidden interaction paths, and validating that the infinite‑scroll component behaves correctly under varied user personas.
How SUSA Works with Infinite Scroll
SUSA (SUSATest) explores an uploaded APK or a web URL by generating realistic interaction sequences: taps, scrolls, text entry, handling dialogs, and navigating back/up. It does this for multiple persona profiles (curious, impatient, novice, adversarial, elderly, accessibility, power user, etc.). Each persona has its own timing, scroll velocity, and tolerance for errors, which means the same infinite‑scroll list is exercised under a wide range of conditions without writing a single line of test script.
When you point SUSA at a screen that contains an infinite‑scroll list, the platform will:
- Detect scrollable containers using accessibility heuristics.
- Generate scroll gestures that vary in distance, speed, and frequency according to the active persona.
- Monitor network requests and UI changes, flagging any deviations from expected behavior (e.g., missing spinner, duplicate request, crash).
- Record the full interaction trace, allowing you to replay a failing session manually or convert it into an automated script (Appium for Android, Playwright for Web).
Because SUSA learns from each run, it avoids re‑exploring dead ends (e.g., a scroll that never triggers a load because the threshold is mis‑configured) and focuses on novel paths in subsequent executions.
Integrating SUSA Results into Your Test Matrix
Take the outcomes of an SUSA run and map them to your existing test‑case IDs:
| SUSA Observation | Corresponding Test Case ID | Action |
|---|---|---|
| Spinner never appears when scrolling fast with “impatient” persona | IS-004, ISN-001 | Add a negative case for high‑velocity scroll with simulated latency |
| Duplicate network request observed when “power user” performs two‑finger scroll then lift | IS-008 | Refine duplicate‑request guard logic |
| Screen reader fails to announce new items for “elderly” persona with large font | IS-010, ISN-008 | Verify ARIA live region updates on dynamic insertion |
| App crashes after 150 rapid scrolls with “adversarial” persona (random taps) | ISE-005, ISP-009 | Stress‑test memory and listener leaks |
End‑of‑list banner not shown when backend returns empty array with hasMore:true for “novice” persona | ISN-004, ISE-002 | Clarify handling of empty pages |
By converting SUSA findings into additional test cases (or updating existing ones), you close gaps that manual design alone might miss. Moreover, you can automate the replay of a failing SUSA session as a regression test, ensuring the same fault does not reappear.
Example: Running SUSA on a Web Infinite‑Scroll Feed
# Install the SUSA agent (once)
pip install susatest-agent
# Point SUSA at your staging URL, request a 10‑minute exploration,
# and ask for an Appium/Playwright script export on failure.
susatest explore \
--url https://staging.example.com/feed \
--personas curious impatient novice elderly accessibility power user \
--duration 10m \
--output-dir ./susa-output \
--on-failure export-playwright \
--export-path ./tests/susa-failed.spec.js
The command above will:
- Launch a headless browser, navigate to the feed, and start scrolling.
- Apply each persona’s behavior profile (e.g., “impatient” uses short scroll bursts with minimal waiting).
- Capture network logs, console errors, and UI snapshots.
- If a crash, ANR, or WCAG violation occurs, it exports a Playwright test that reproduces the exact interaction sequence, which you can then add to your CI pipeline.
Limit SUSA usage to at most two sections in this article (this section and the checklist that follows) to stay within the guideline.
Checklist for Infinite Scroll Test Suites
Use this concise checklist before marking a story as done. Tick each item only after you have evidence (manual test pass, automated test pass, or SUSA finding) that satisfies it.
- [ ] Basic load – First page renders and spinner appears on approach (IS-001).
- [ ] Correct pagination – Subsequent scrolls request the next offset without duplicates (IS-002, IS-008).
- [ ] Item integrity – No missing, duplicated, or out‑of‑order items after N loads (IS-003).
- [ ] Loading feedback – Spinner visible during request, hidden on success/error (IS-004, ISN-001/02).
- [ ] Placeholder stability – No layout jump when placeholders replace real data (IS-005).
- [ ] Termination – End‑of‑list message shows when backend signals no more data (IS-006, ISE-002).
- [ ] Error handling – Network timeout, HTTP 5xx, malformed JSON, and offline states show retry UI without crashing (ISN-001‑004, ISN-005‑006).
- [ ] Recovery – Retry clears error and fetches next page successfully (ISN-007).
- [ ] Accessibility – Keyboard, mouse wheel, and screen‑reader interactions trigger loads and announce changes (IS-009, IS-010, ISE-006, ISN-008).
- [ ] Orientation & modality – Scroll position preserved on rotation; modal overlays block background loads (IS-011, ISE-009).
- [ ] Performance – Frame time ≤ 16 ms for 95 % of frames; memory growth bounded memory increase < 2 MB per 100 items; TTI ≤ 300 ms on 3G (ISP‑series).
- [ ] Stress & longevity – No OOM or listener leak after hours of scrolling; works on low‑end devices (ISE-005, ISP-009).
- [ ] Cross‑platform – Behaviors consistent on Android native, iOS native, and web (run same matrix on each platform).
- [ ] Persona coverage – SUSA run with all eight personas produces no new failures; any failures are converted to test cases.
- [ ] Traceability – Every test case maps to at least one requirement ID (see traceability table).
- [ ] **Automation
Test Your App Autonomously
Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts.
Try SUSA Free