docs: add comprehensive testing and recovery documentation
- Add app-startup-recovery-solution.md with technical deep dive - Add boot-receiver-testing-guide.md with Android 10+ fixes - Add notification-testing-procedures.md with manual testing steps - Add reboot-testing-procedure.md with automated testing - Add reboot-testing-steps.md with quick reference guide - Add testing-quick-reference.md with common scenarios Documentation covers: - Boot receiver implementation and Direct Boot handling - App startup recovery as fallback mechanism - Comprehensive testing procedures for all scenarios - Troubleshooting guides for common issues - Performance metrics and success criteria - Production deployment best practices This provides complete documentation for the notification system including both boot receiver and app startup recovery approaches.
This commit is contained in:
518
docs/notification-testing-procedures.md
Normal file
518
docs/notification-testing-procedures.md
Normal file
@@ -0,0 +1,518 @@
|
||||
# DailyNotification Plugin Testing Procedures
|
||||
|
||||
## Overview
|
||||
|
||||
This document provides comprehensive testing procedures for the DailyNotification Capacitor plugin, covering both manual and automated testing scenarios.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Manual Testing Procedures](#manual-testing-procedures)
|
||||
2. [Scripted Testing Procedures](#scripted-testing-procedures)
|
||||
3. [ADB Commands Reference](#adb-commands-reference)
|
||||
4. [Troubleshooting](#troubleshooting)
|
||||
5. [Test Scenarios](#test-scenarios)
|
||||
|
||||
---
|
||||
|
||||
## Manual Testing Procedures
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Android device or emulator with ADB enabled
|
||||
- DailyNotification app installed
|
||||
- ADB tools installed on development machine
|
||||
- Notification permissions granted
|
||||
|
||||
### Basic Functionality Test
|
||||
|
||||
#### 1. Plugin Registration Test
|
||||
|
||||
**Objective**: Verify the plugin loads and registers correctly
|
||||
|
||||
**Steps**:
|
||||
1. Launch the app: `adb shell am start -n com.timesafari.dailynotification/.MainActivity`
|
||||
2. Tap "Test Plugin" button
|
||||
3. Verify status shows "Plugin is working! Echo result: Hello from test app!"
|
||||
|
||||
**Expected Result**: Green status with successful echo response
|
||||
|
||||
#### 2. Permission Management Test
|
||||
|
||||
**Objective**: Test permission request and status checking
|
||||
|
||||
**Steps**:
|
||||
1. Tap "Check Permissions" button
|
||||
2. Note current permission status (✅/❌ indicators)
|
||||
3. Tap "Request Permissions" button
|
||||
4. Grant permissions in system dialog if prompted
|
||||
5. Tap "Check Permissions" again to verify
|
||||
|
||||
**Expected Result**: All permissions show ✅ after granting
|
||||
|
||||
#### 3. Notification Scheduling Test
|
||||
|
||||
**Objective**: Test basic notification scheduling
|
||||
|
||||
**Steps**:
|
||||
1. Tap "Test Notification" button
|
||||
2. Verify status shows "Notification scheduled for [time]!"
|
||||
3. Wait 1 minute for notification to appear
|
||||
4. Check notification panel for the test notification
|
||||
|
||||
**Expected Result**: Notification appears in system notification panel
|
||||
|
||||
### Background Notification Test
|
||||
|
||||
#### 4. App Background Notification Test
|
||||
|
||||
**Objective**: Verify notifications work when app is in background
|
||||
|
||||
**Steps**:
|
||||
1. Schedule a notification using "Test Notification"
|
||||
2. Send app to background: `adb shell input keyevent KEYCODE_HOME`
|
||||
3. Verify app is still running: `adb shell "ps | grep timesafari"`
|
||||
4. Wait for scheduled time
|
||||
5. Check notification panel
|
||||
|
||||
**Expected Result**: Notification appears even with app in background
|
||||
|
||||
#### 5. App Closed Notification Test
|
||||
|
||||
**Objective**: Verify notifications work when app is closed normally
|
||||
|
||||
**Steps**:
|
||||
1. Schedule a notification using "Test Notification"
|
||||
2. Close app normally: `adb shell input keyevent KEYCODE_HOME`
|
||||
3. Verify app process is still running: `adb shell "ps | grep timesafari"`
|
||||
4. Wait for scheduled time
|
||||
5. Check notification panel
|
||||
|
||||
**Expected Result**: Notification appears with app closed
|
||||
|
||||
### Edge Case Testing
|
||||
|
||||
#### 6. Force Stop Test (Expected Failure)
|
||||
|
||||
**Objective**: Verify force-stop cancels notifications (expected behavior)
|
||||
|
||||
**Steps**:
|
||||
1. Schedule a notification using "Test Notification"
|
||||
2. Force stop the app: `adb shell am force-stop com.timesafari.dailynotification`
|
||||
3. Verify app is killed: `adb shell "ps | grep timesafari"` (should return nothing)
|
||||
4. Wait for scheduled time
|
||||
5. Check notification panel
|
||||
|
||||
**Expected Result**: No notification appears (this is correct behavior)
|
||||
|
||||
#### 7. Reboot Recovery Test
|
||||
|
||||
**Objective**: Test notification recovery after device reboot
|
||||
|
||||
**Steps**:
|
||||
1. Schedule a notification for future time
|
||||
2. Reboot device: `adb reboot`
|
||||
3. Wait for device to fully boot
|
||||
4. Check if notification still scheduled: `adb shell "dumpsys alarm | grep timesafari"`
|
||||
5. Wait for scheduled time
|
||||
6. Check notification panel
|
||||
|
||||
**Expected Result**: Notification should still fire after reboot
|
||||
|
||||
---
|
||||
|
||||
## Scripted Testing Procedures
|
||||
|
||||
### Automated Test Script
|
||||
|
||||
Create a test script for automated testing:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# daily-notification-test.sh
|
||||
|
||||
set -e
|
||||
|
||||
APP_PACKAGE="com.timesafari.dailynotification"
|
||||
APP_ACTIVITY=".MainActivity"
|
||||
TEST_TIMEOUT=120 # 2 minutes
|
||||
|
||||
echo "🧪 Starting DailyNotification Plugin Tests"
|
||||
echo "=========================================="
|
||||
|
||||
# Function to check if app is running
|
||||
check_app_running() {
|
||||
adb shell "ps | grep $APP_PACKAGE" > /dev/null 2>&1
|
||||
}
|
||||
|
||||
# Function to wait for app to be ready
|
||||
wait_for_app() {
|
||||
echo "⏳ Waiting for app to be ready..."
|
||||
sleep 3
|
||||
}
|
||||
|
||||
# Function to schedule notification
|
||||
schedule_notification() {
|
||||
echo "📅 Scheduling test notification..."
|
||||
# This would need to be implemented with UI automation
|
||||
# For now, we'll assume manual scheduling
|
||||
echo "⚠️ Manual step: Schedule notification in app UI"
|
||||
read -p "Press Enter when notification is scheduled..."
|
||||
}
|
||||
|
||||
# Test 1: App Launch
|
||||
echo "🚀 Test 1: App Launch"
|
||||
adb shell am start -n $APP_PACKAGE/$APP_ACTIVITY
|
||||
wait_for_app
|
||||
|
||||
if check_app_running; then
|
||||
echo "✅ App launched successfully"
|
||||
else
|
||||
echo "❌ App failed to launch"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Test 2: Background Test
|
||||
echo "🔄 Test 2: Background Notification Test"
|
||||
schedule_notification
|
||||
|
||||
echo "📱 Sending app to background..."
|
||||
adb shell input keyevent KEYCODE_HOME
|
||||
sleep 2
|
||||
|
||||
if check_app_running; then
|
||||
echo "✅ App running in background"
|
||||
else
|
||||
echo "❌ App not running in background"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Test 3: Wait for notification
|
||||
echo "⏰ Test 3: Waiting for notification ($TEST_TIMEOUT seconds)..."
|
||||
echo "👀 Watch for notification in system panel"
|
||||
|
||||
# Check for notification in logs
|
||||
timeout $TEST_TIMEOUT bash -c '
|
||||
while true; do
|
||||
if adb logcat -d | grep -q "Notification displayed successfully"; then
|
||||
echo "✅ Notification displayed successfully"
|
||||
exit 0
|
||||
fi
|
||||
sleep 5
|
||||
done
|
||||
'
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✅ Notification test passed"
|
||||
else
|
||||
echo "❌ Notification test failed or timed out"
|
||||
fi
|
||||
|
||||
# Test 4: Force Stop Test
|
||||
echo "🛑 Test 4: Force Stop Test (Expected Failure)"
|
||||
schedule_notification
|
||||
|
||||
echo "💀 Force stopping app..."
|
||||
adb shell am force-stop $APP_PACKAGE
|
||||
sleep 2
|
||||
|
||||
if check_app_running; then
|
||||
echo "❌ App still running after force stop"
|
||||
exit 1
|
||||
else
|
||||
echo "✅ App successfully force stopped"
|
||||
fi
|
||||
|
||||
echo "⏰ Waiting for notification (should NOT appear)..."
|
||||
sleep 60
|
||||
|
||||
if adb logcat -d | grep -q "Notification displayed successfully"; then
|
||||
echo "❌ Notification appeared after force stop (unexpected)"
|
||||
else
|
||||
echo "✅ No notification after force stop (expected)"
|
||||
fi
|
||||
|
||||
echo "🎉 All tests completed!"
|
||||
```
|
||||
|
||||
### Python Test Script
|
||||
|
||||
For more advanced testing with UI automation:
|
||||
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
DailyNotification Plugin Automated Test Suite
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import time
|
||||
import json
|
||||
import sys
|
||||
from typing import Optional, Dict, Any
|
||||
|
||||
class DailyNotificationTester:
|
||||
def __init__(self, package: str = "com.timesafari.dailynotification"):
|
||||
self.package = package
|
||||
self.activity = f"{package}/.MainActivity"
|
||||
|
||||
def run_adb_command(self, command: str) -> subprocess.CompletedProcess:
|
||||
"""Run ADB command and return result"""
|
||||
return subprocess.run(
|
||||
f"adb {command}",
|
||||
shell=True,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
|
||||
def is_app_running(self) -> bool:
|
||||
"""Check if app is currently running"""
|
||||
result = self.run_adb_command(f'shell "ps | grep {self.package}"')
|
||||
return result.returncode == 0 and self.package in result.stdout
|
||||
|
||||
def launch_app(self) -> bool:
|
||||
"""Launch the app"""
|
||||
result = self.run_adb_command(f"shell am start -n {self.activity}")
|
||||
time.sleep(3) # Wait for app to load
|
||||
return self.is_app_running()
|
||||
|
||||
def send_to_background(self) -> bool:
|
||||
"""Send app to background"""
|
||||
self.run_adb_command("shell input keyevent KEYCODE_HOME")
|
||||
time.sleep(2)
|
||||
return self.is_app_running()
|
||||
|
||||
def force_stop_app(self) -> bool:
|
||||
"""Force stop the app"""
|
||||
self.run_adb_command(f"shell am force-stop {self.package}")
|
||||
time.sleep(2)
|
||||
return not self.is_app_running()
|
||||
|
||||
def check_notification_logs(self, timeout: int = 60) -> bool:
|
||||
"""Check for notification success in logs"""
|
||||
start_time = time.time()
|
||||
while time.time() - start_time < timeout:
|
||||
result = self.run_adb_command("logcat -d")
|
||||
if "Notification displayed successfully" in result.stdout:
|
||||
return True
|
||||
time.sleep(5)
|
||||
return False
|
||||
|
||||
def run_test_suite(self) -> Dict[str, Any]:
|
||||
"""Run complete test suite"""
|
||||
results = {}
|
||||
|
||||
print("🧪 Starting DailyNotification Test Suite")
|
||||
print("=" * 50)
|
||||
|
||||
# Test 1: App Launch
|
||||
print("🚀 Test 1: App Launch")
|
||||
results["app_launch"] = self.launch_app()
|
||||
print(f"Result: {'✅ PASS' if results['app_launch'] else '❌ FAIL'}")
|
||||
|
||||
# Test 2: Background Test
|
||||
print("🔄 Test 2: Background Test")
|
||||
results["background"] = self.send_to_background()
|
||||
print(f"Result: {'✅ PASS' if results['background'] else '❌ FAIL'}")
|
||||
|
||||
# Test 3: Force Stop Test
|
||||
print("🛑 Test 3: Force Stop Test")
|
||||
results["force_stop"] = self.force_stop_app()
|
||||
print(f"Result: {'✅ PASS' if results['force_stop'] else '❌ FAIL'}")
|
||||
|
||||
# Test 4: Notification Test (requires manual scheduling)
|
||||
print("📱 Test 4: Notification Test")
|
||||
print("⚠️ Manual step required: Schedule notification in app")
|
||||
input("Press Enter when notification is scheduled...")
|
||||
|
||||
results["notification"] = self.check_notification_logs()
|
||||
print(f"Result: {'✅ PASS' if results['notification'] else '❌ FAIL'}")
|
||||
|
||||
return results
|
||||
|
||||
def main():
|
||||
tester = DailyNotificationTester()
|
||||
results = tester.run_test_suite()
|
||||
|
||||
print("\n📊 Test Results Summary:")
|
||||
print("=" * 30)
|
||||
for test, passed in results.items():
|
||||
status = "✅ PASS" if passed else "❌ FAIL"
|
||||
print(f"{test.replace('_', ' ').title()}: {status}")
|
||||
|
||||
# Exit with error code if any test failed
|
||||
if not all(results.values()):
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ADB Commands Reference
|
||||
|
||||
### App Management Commands
|
||||
|
||||
```bash
|
||||
# Launch app
|
||||
adb shell am start -n com.timesafari.dailynotification/.MainActivity
|
||||
|
||||
# Send to background (normal close)
|
||||
adb shell input keyevent KEYCODE_HOME
|
||||
|
||||
# Force stop app
|
||||
adb shell am force-stop com.timesafari.dailynotification
|
||||
|
||||
# Check if app is running
|
||||
adb shell "ps | grep timesafari"
|
||||
|
||||
# Clear app data
|
||||
adb shell pm clear com.timesafari.dailynotification
|
||||
```
|
||||
|
||||
### Notification Testing Commands
|
||||
|
||||
```bash
|
||||
# Check notification settings
|
||||
adb shell "dumpsys notification | grep -A5 -B5 timesafari"
|
||||
|
||||
# List all notifications
|
||||
adb shell "cmd notification list"
|
||||
|
||||
# Open notification settings
|
||||
adb shell "am start -a android.settings.APP_NOTIFICATION_SETTINGS -e android.provider.extra.APP_PACKAGE com.timesafari.dailynotification"
|
||||
```
|
||||
|
||||
### Alarm Management Commands
|
||||
|
||||
```bash
|
||||
# Check scheduled alarms
|
||||
adb shell "dumpsys alarm | grep -i alarm"
|
||||
|
||||
# Check specific app alarms
|
||||
adb shell "dumpsys alarm | grep timesafari"
|
||||
|
||||
# Check exact alarm permissions
|
||||
adb shell "dumpsys alarm | grep SCHEDULE_EXACT_ALARM"
|
||||
```
|
||||
|
||||
### Logging Commands
|
||||
|
||||
```bash
|
||||
# Monitor logs in real-time
|
||||
adb logcat | grep -i "dailynotification\|notification"
|
||||
|
||||
# Get recent logs
|
||||
adb logcat -d | grep -i "dailynotification"
|
||||
|
||||
# Clear logs
|
||||
adb logcat -c
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
#### 1. Plugin Not Loading
|
||||
**Symptoms**: "Plugin not available" error
|
||||
**Solutions**:
|
||||
- Check `capacitor.plugins.json` file exists and is valid
|
||||
- Verify plugin is built: `./gradlew assembleDebug`
|
||||
- Reinstall app: `adb install -r app/build/outputs/apk/debug/app-debug.apk`
|
||||
|
||||
#### 2. Notifications Not Appearing
|
||||
**Symptoms**: No notification in system panel
|
||||
**Solutions**:
|
||||
- Check notification permissions: Use "Check Permissions" button
|
||||
- Verify notification importance: `adb shell "dumpsys notification | grep timesafari"`
|
||||
- Check if notifications are enabled in system settings
|
||||
|
||||
#### 3. Alarms Not Firing
|
||||
**Symptoms**: Scheduled notifications don't appear
|
||||
**Solutions**:
|
||||
- Check exact alarm permissions: `adb shell "dumpsys alarm | grep SCHEDULE_EXACT_ALARM"`
|
||||
- Verify alarm is scheduled: `adb shell "dumpsys alarm | grep timesafari"`
|
||||
- Check battery optimization settings
|
||||
|
||||
#### 4. App Crashes on Force Stop
|
||||
**Symptoms**: App crashes when force-stopped
|
||||
**Solutions**:
|
||||
- This is expected behavior - force-stop kills the app
|
||||
- Use normal closure for testing: `adb shell input keyevent KEYCODE_HOME`
|
||||
|
||||
### Debug Commands
|
||||
|
||||
```bash
|
||||
# Check app permissions
|
||||
adb shell dumpsys package com.timesafari.dailynotification | grep permission
|
||||
|
||||
# Check app info
|
||||
adb shell dumpsys package com.timesafari.dailynotification | grep -A10 "Application Info"
|
||||
|
||||
# Check notification channels
|
||||
adb shell "dumpsys notification | grep -A10 timesafari"
|
||||
|
||||
# Monitor system events
|
||||
adb shell "dumpsys activity activities | grep timesafari"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Test Scenarios
|
||||
|
||||
### Scenario 1: Basic Functionality
|
||||
- **Objective**: Verify plugin works in normal conditions
|
||||
- **Steps**: Launch app → Test plugin → Schedule notification → Verify delivery
|
||||
- **Expected**: All functions work correctly
|
||||
|
||||
### Scenario 2: Background Operation
|
||||
- **Objective**: Verify notifications work with app in background
|
||||
- **Steps**: Schedule notification → Send to background → Wait for delivery
|
||||
- **Expected**: Notification appears despite app being backgrounded
|
||||
|
||||
### Scenario 3: Permission Management
|
||||
- **Objective**: Test permission request and status
|
||||
- **Steps**: Check permissions → Request permissions → Verify status
|
||||
- **Expected**: Permissions granted and status updated
|
||||
|
||||
### Scenario 4: Edge Cases
|
||||
- **Objective**: Test behavior under extreme conditions
|
||||
- **Steps**: Force stop → Reboot → Battery optimization
|
||||
- **Expected**: Graceful handling of edge cases
|
||||
|
||||
### Scenario 5: Performance Testing
|
||||
- **Objective**: Test under load and stress
|
||||
- **Steps**: Multiple notifications → Rapid scheduling → Memory pressure
|
||||
- **Expected**: Stable performance under load
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Testing Environment
|
||||
- Use physical device for most accurate results
|
||||
- Test on multiple Android versions (API 21+)
|
||||
- Test on different OEMs (Samsung, Huawei, etc.)
|
||||
- Test with different battery optimization settings
|
||||
|
||||
### Test Data
|
||||
- Use realistic notification content
|
||||
- Test with various time intervals
|
||||
- Test with different notification priorities
|
||||
- Test with sound/vibration enabled/disabled
|
||||
|
||||
### Documentation
|
||||
- Record test results with timestamps
|
||||
- Screenshot notification appearances
|
||||
- Log any errors or unexpected behavior
|
||||
- Document device-specific issues
|
||||
|
||||
---
|
||||
|
||||
## Conclusion
|
||||
|
||||
This testing procedure ensures the DailyNotification plugin works correctly across all scenarios. Regular testing helps maintain reliability and catch issues early in development.
|
||||
|
||||
For questions or issues, refer to the troubleshooting section or check the plugin logs using the provided ADB commands.
|
||||
Reference in New Issue
Block a user