Add integration guides and update API documentation with new Android diagnostic methods. Emphasize critical NotifyReceiver registration requirement that was causing notification delivery failures. Documentation Updates: - API.md: Document isAlarmScheduled(), getNextAlarmTime(), testAlarm() - README.md: Add Quick Integration section and Android diagnostic methods - notification-testing-procedures.md: Add BroadcastReceiver troubleshooting New Integration Guides: - QUICK_INTEGRATION.md: Step-by-step guide for human developers - AI_INTEGRATION_GUIDE.md: Machine-readable guide with verification steps - TODO.md: Task tracking for pending improvements Key Improvements: - Explicit NotifyReceiver registration requirement highlighted - Complete troubleshooting flow for BroadcastReceiver issues - Diagnostic method examples for debugging alarm scheduling - AI-friendly integration instructions with verification commands Fixes notification delivery issues caused by missing NotifyReceiver registration in host app AndroidManifest.xml files.
547 lines
16 KiB
Markdown
547 lines
16 KiB
Markdown
# 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 loaded and ready!"
|
|
|
|
**Expected Result**: Green status with plugin loaded confirmation
|
|
|
|
#### 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
|
|
- Use diagnostic methods to verify alarm status:
|
|
```typescript
|
|
// Check if alarm is scheduled
|
|
const status = await DailyNotification.isAlarmScheduled({
|
|
triggerAtMillis: scheduledTime
|
|
});
|
|
|
|
// Get next alarm time
|
|
const nextAlarm = await DailyNotification.getNextAlarmTime();
|
|
|
|
// Test alarm delivery
|
|
await DailyNotification.testAlarm({ secondsFromNow: 10 });
|
|
```
|
|
|
|
#### 4. BroadcastReceiver Not Invoked
|
|
**Symptoms**: Alarm fires but notification doesn't appear, no logs from `NotifyReceiver`
|
|
**Solutions**:
|
|
- **CRITICAL**: Verify `NotifyReceiver` is registered in `AndroidManifest.xml`:
|
|
```xml
|
|
<receiver android:name="com.timesafari.dailynotification.NotifyReceiver"
|
|
android:enabled="true"
|
|
android:exported="false">
|
|
</receiver>
|
|
```
|
|
- Check logs for `NotifyReceiver` registration: `adb logcat -d | grep -i "NotifyReceiver"`
|
|
- Verify the receiver is in your app's manifest, not just the plugin's manifest
|
|
- Check if app process is killed: `adb shell "ps | grep timesafari"`
|
|
- Review alarm scheduling logs: `adb logcat -d | grep -E "DNP-NOTIFY|Alarm clock"`
|
|
|
|
#### 5. 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.
|