# Test Steps: Location Features # HRMS Check-in/Check-out System ## Document Information | Field | Value | |-------|-------| | **Document Version** | 1.0.0 | | **Last Updated** | 2025-03-09 | | **Project** | HRMS Check-in/Check-out | | **Module** | Location Features | | **Author** | QA Team | --- ## Table of Contents 1. [Overview](#1-overview) 2. [Test Environment Setup](#2-test-environment-setup) 3. [Manual Testing Procedures](#3-manual-testing-procedures) 4. [Mock Location Testing](#4-mock-location-testing) 5. [Developer Tools Testing](#5-developer-tools-testing) 6. [Device-Specific Testing](#6-device-specific-testing) 7. [Test Data & Scenarios](#7-test-data--scenarios) 8. [Troubleshooting](#8-troubleshooting) --- ## 1. Overview เอกสารนี้ประกอบด้วยขั้นตอนการทดสอบ (Test Steps) แบบละเอียดสำหรับการทดสอบฟีเจอร์ Location ของระบบ HRMS Check-in/Check-out โดยเน้นการทดสอบแบบ Manual Testing และการจำลองสถานการณ์ต่าง ๆ ### 1.1 Testing Scope | Area | Description | |------|-------------| | **Location Permission** | การขอและการจัดการสิทธิ์การเข้าถึงตำแหน่ง | | **Location Acquisition** | การรับพิกัด GPS จากอุปกรณ์ | | **Location Validation** | การตรวจสอบความถูกต้องของตำแหน่ง | | **Mock Detection** | การตรวจจับการจำลองตำแหน่ง | | **POI Resolution** | การแปลงพิกัดเป็นชื่อสถานที่ | | **Check-in/Check-out** | การลงเวลาเข้า-ออกงานพร้อมตำแหน่ง | | **Privacy Consent** | การขอความยินยอมการใช้ข้อมูล | --- ## 2. Test Environment Setup ### 2.1 Device Preparation #### 2.1.1 Android Device Setup 1. **Enable Developer Options** - เปิด Settings > About Phone - แตะที่ Build Number 7 ครั้ง - กลับมาที่ Settings > Developer Options 2. **Enable Mock Location (สำหรับการทดสอบ)** - เปิด Settings > Developer Options - เลือก "Select mock location app" - เลือก Fake GPS Location App ที่ติดตั้ง 3. **Install Fake GPS Apps** - Fake GPS Location (by Lexa) - [Google Play](https://play.google.com/store/apps/details?id=com.lexa.fakegps) - GPS Joystick - [Google Play](https://play.google.com/store/apps/details?id=com.theappninjas.android.gpsjoke) #### 2.1.2 iOS Device Setup 1. **Xcode Simulation (ต้องใช้ Mac)** - เปิด Xcode - เลือก Device > Debug Location > Custom Location... - ป้อน Latitude และ Longitude 2. **Location Changer Apps** - Location Changer - [App Store](https://apps.apple.com/app/location-changer/id1383869695) #### 2.1.3 Desktop Browser Setup 1. **Chrome DevTools** - กด F12 หรือ Cmd+Option+I (Mac) / Ctrl+Shift+I (Windows) - เลือก More tools > Sensors - ตั้งค่า Location ใน Sensors tab 2. **Edge DevTools** - กด F12 - เลือก More tools > Sensors - ตั้งค่า Location ใน Sensors tab ### 2.2 Network Setup | Scenario | Setup | |----------|-------| | **Normal Network** | WiFi/4G/5G เชื่อมต่อปกติ | | **Slow Network** | Chrome DevTools > Network > Throttling > Slow 3G | | **Offline** | Chrome DevTools > Network > Offline | | **GPS Blocking** | Disable Location Service ในระบบ | ### 2.3 Test Location Data | Location Name | Latitude | Longitude | Notes | |---------------|----------|-----------|-------| | Sanam Suea Pa (สนามเสือป่า) | 13.7563 | 100.5018 | Bangkok Government Office | | Suvarnabhumi Airport | 13.6900 | 100.7501 | Outdoor, high GPS accuracy | | Central World | 13.7944 | 100.5439 | Indoor shopping mall | | Null Island | 0 | 0 | Default mock location (invalid) | | Out of Range | 91 | 181 | Invalid coordinates | | Chiang Mai | 18.7883 | 98.9853 | Northern Thailand | --- ## 3. Manual Testing Procedures ### 3.1 TC-LOC-01: Location Permission Testing #### Test Case: TC-LOC-01-01 - อนุญาตให้เข้าถึงตำแหน่ง **Objective**: ทดสอบการอนุญาตให้เข้าถึงตำแหน่ง | Step | Action | Expected Result | Screenshot | |------|--------|-----------------|------------| | 1 | เปิดแอป HRMS ครั้งแรก | แสดงหน้าแรกของแอป | [ ] | | 2 | แสดง Privacy Modal (ถ้ายังไม่ยอมรับ) | แสดง Privacy Policy Modal | [ ] | | 3 | กด "ยอมรับ" เพื่อยอมรับ Privacy Policy | Modal ปิด, `isAccepted = true` | [ ] | | 4 | กดปุ่มขอตำแหน่ง (mapRef.requestLocationPermission()) | ระบบขอ Location Permission | [ ] | | 5 | เลือก "Allow" เมื่อระบบขอ Location Permission | รับสิทธิ์สำเร็จ | [ ] | | 6 | รอรับพิกัด GPS | แสดง Skeleton loading | [ ] | | 7 | รับพิกัดสำเร็จ | แสดงแผนที่พร้อมตำแหน่งปัจจุบัน | [ ] | | 8 | ตรวจสอบชื่อสถานที่ใกล้เคียง | แสดงชื่อสถานที่ (POI) | [ ] | | 9 | ตรวจสอบสถานะปุ่มลงเวลา | ปุ่มใช้งานได้ (disabled = false) | [ ] | **Verification Checklist:** - [ ] แผนที่แสดงตำแหน่งปัจจุบันถูกต้อง - [ ] ชื่อสถานที่ใกล้เคียงแสดงถูกต้อง - [ ] `locationGranted = true` - [ ] ปุ่มลงเวลาเข้า/ออกใช้งานได้ - [ ] ไม่มีข้อความ error แสดงขึ้น --- #### Test Case: TC-LOC-01-02 - ปฏิเสธการเข้าถึงตำแหน่ง **Objective**: ทดสอบการปฏิเสธการเข้าถึงตำแหน่ง | Step | Action | Expected Result | Screenshot | |------|--------|-----------------|------------| | 1 | เปิดแอป HRMS ครั้งแรก | แสดงหน้าแรกของแอป | [ ] | | 2 | ยอมรับ Privacy Policy | Modal ปิด | [ ] | | 3 | กดปุ่มขอตำแหน่ง | ระบบขอ Location Permission | [ ] | | 4 | เลือก "Deny" เมื่อระบบขอ Location Permission | ปฏิเสธสิทธิ์ | [ ] | | 5 | ตรวจสอบ error message | แสดง "ไม่สามารถระบุตำแหน่งปัจจุบันได้ เนื่องจากคุณปฏิเสธการเข้าถึงตำแหน่ง กรุณาเปิดการเข้าถึงตำแหน่ง" | [ ] | | 6 | ตรวจสอบแผนที่ | แผนที่ไม่แสดง (poiPlaceName = '') | [ ] | | 7 | ตรวจสอบปุ่มลงเวลา | ปุ่มใช้งานไม่ได้ (disabled = true) | [ ] | **Verification Checklist:** - [ ] แสดง error message ถูกต้อง - [ ] แผนที่ไม่แสดง - [ ] `locationGranted = false` - [ ] ปุ่มลงเวลาเข้า/ออก disabled - [ ] ไม่สามารถลงเวลาได้ --- ### 3.2 TC-LOC-02: Location Acquisition Testing #### Test Case: TC-LOC-02-01 - รับพิกัด GPS สำเร็จ (Outdoor) **Objective**: ทดสอบการรับพิกัด GPS สำเร็จในพื้นที่เปิดกว้าง | Step | Action | Expected Result | Screenshot | |------|--------|-----------------|------------| | 1 | ไปยังพื้นที่เปิดกว้าง (Outdoor) | อยู่กลางแจ้ง มีสัญญาณ GPS ดี | [ ] | | 2 | เปิดแอป HRMS | แสดงหน้าแรก | [ ] | | 3 | อนุญาต Location Permission | รับสิทธิ์สำเร็จ | [ ] | | 4 | กดปุ่มขอตำแหน่ง | เริ่มรับพิกัด GPS | [ ] | | 5 | รอรับพิกัด (ประมาณ 3-5 วินาที) | แสดง Skeleton loading | [ ] | | 6 | รับพิกัดสำเร็จ | แสดงแผนที่ | [ ] | | 7 | ตรวจสอบพิกัด | Latitude และ Longitude ถูกต้อง | [ ] | | 8 | ตรวจสอบความแม่นยำ | Accuracy <= 100 meters | [ ] | | 9 | ตรวจสอบ timestamp | Timestamp ภายใน 60 วินาที | [ ] | | 10 | ตรวจสอบชื่อสถานที่ | แสดงชื่อสถานที่ใกล้เคียง | [ ] | **Verification Checklist:** - [ ] รับพิกัดสำเร็จ - [ ] พิกัดอยู่ในช่วงที่ถูกต้อง (lat: -90 to 90, lon: -180 to 180) - [ ] ไม่ใช่ (0, 0) - [ ] Accuracy <= 100 meters - [ ] Timestamp ภายใน 60 วินาที - [ ] ชื่อสถานที่ใกล้เคียงแสดงถูกต้อง --- #### Test Case: TC-LOC-02-02 - รับพิกัด GPS สำเร็จ (Indoor) **Objective**: ทดสอบการรับพิกัด GPS สำเร็จในพื้นที่ปิด | Step | Action | Expected Result | Screenshot | |------|--------|-----------------|------------| | 1 | ไปยังพื้นที่ปิด (Indoor) | อยู่ภายในอาคาร | [ ] | | 2 | เปิดแอป HRMS | แสดงหน้าแรก | [ ] | | 3 | อนุญาต Location Permission | รับสิทธิ์สำเร็จ | [ ] | | 4 | กดปุ่มขอตำแหน่ง | เริ่มรับพิกัด GPS | [ ] | | 5 | รอรับพิกัด (อาจนานกว่าปกติ) | แสดง Skeleton loading | [ ] | | 6 | รับพิกัดสำเร็จ | แสดงแผนที่ | [ ] | | 7 | ตรวจสอบพิกัด | Latitude และ Longitude ถูกต้อง | [ ] | | 8 | ตรวจสอบความแม่นยำ | อาจมีความแม่นยำต่ำกว่า Outdoor | [ ] | **Verification Checklist:** - [ ] รับพิกัดสำเร็จ - [ ] อาจมีความแม่นยำต่ำกว่า Outdoor - [ ] แผนที่แสดงถูกต้อง --- #### Test Case: TC-LOC-02-03 - รับพิกัด GPS ล้มเหลว (GPS ไม่ทำงาน) **Objective**: ทดสอบกรณี GPS ไม่ทำงาน | Step | Action | Expected Result | Screenshot | |------|--------|-----------------|------------| | 1 | เปิดแอป HRMS | แสดงหน้าแรก | [ ] | | 2 | อนุญาต Location Permission | รับสิทธิ์สำเร็จ | [ ] | | 3 | ไปที่ Settings > Location > ปิด GPS | GPS ปิดอยู่ | [ ] | | 4 | กดปุ่มขอตำแหน่ง | เริ่มรับพิกัด GPS | [ ] | | 5 | ตรวจสอบ error message | แสดง "ไม่สามารถระบุตำแหน่งปัจจุบันได้" | [ ] | | 6 | ตรวจสอบแผนที่ | แผนที่ไม่แสดง | [ ] | **Verification Checklist:** - [ ] แสดง error message ถูกต้อง - [ ] แผนที่ไม่แสดง - [ ] ไม่สามารถรับพิกัดได้ --- ### 3.3 TC-LOC-03: Location Validation Testing #### Test Case: TC-LOC-03-01 - พิกัดถูกต้อง (Valid coordinates) **Objective**: ทดสอบการตรวจสอบพิกัดที่ถูกต้อง | Step | Action | Expected Result | Screenshot | |------|--------|-----------------|------------| | 1 | เปิดแอป HRMS | แสดงหน้าแรก | [ ] | | 2 | อนุญาต Location Permission | รับสิทธิ์สำเร็จ | [ ] | | 3 | รับพิกัด GPS ปกติ | พิกัดถูกต้อง (เช่น 13.7563, 100.5018) | [ ] | | 4 | เปิด Console และตรวจสอบ validationResult | { isValid: true, isMockDetected: false } | [ ] | | 5 | ตรวจสอบ locationGranted | locationGranted = true | [ ] | | 6 | ตรวจสอบปุ่มลงเวลา | ปุ่มใช้งานได้ | [ ] | **Verification Checklist:** - [ ] `validationResult.isValid = true` - [ ] `validationResult.isMockDetected = false` - [ ] `validationResult.errors = []` - [ ] `locationGranted = true` - [ ] ไม่มี error/warning message --- #### Test Case: TC-LOC-03-02 - พิกัดไม่ถูกต้อง (Invalid coordinates - (0,0)) **Objective**: ทดสอบการตรวจสอบพิกัด (0,0) | Step | Action | Expected Result | Screenshot | |------|--------|-----------------|------------| | 1 | เปิด Fake GPS App | เปิดแอป | [ ] | | 2 | ตั้งค่าพิกัด (0, 0) | Latitude: 0, Longitude: 0 | [ ] | | 3 | เปิดแอป HRMS | แสดงหน้าแรก | [ ] | | 4 | กดปุ่มขอตำแหน่ง | เริ่มรับพิกัด GPS | [ ] | | 5 | ตรวจสอบ Console (validateCoordinates) | validateCoordinates(0, 0) = false | [ ] | | 6 | ตรวจสอบ validationResult | { isValid: false, isMockDetected: true, confidence: 'high' } | [ ] | | 7 | ตรวจสอบ error message | "พิกัดตำแหน่งไม่ถูกต้อง กรุณาลองใหม่" | [ ] | | 8 | ตรวจสอบ disabledBtn | disabledBtn = true | [ ] | **Verification Checklist:** - [ ] `validateCoordinates(0, 0) = false` - [ ] `mockIndicators = 3` - [ ] `isMockDetected = true` - [ ] `confidence = 'high'` - [ ] แสดง error message ถูกต้อง - [ ] ปุ่มลงเวลา disabled --- #### Test Case: TC-LOC-03-04 - ข้อมูลตำแหน่งเก่าเกินไป (Stale timestamp) **Objective**: ทดสอบการตรวจสอบ timestamp เก่าเกิน 60 วินาที | Step | Action | Expected Result | Screenshot | |------|--------|-----------------|------------| | 1 | เปิด Chrome DevTools | F12 > Sensors | [ ] | | 2 | เลือก Custom Location | กำหนดพิกัด | [ ] | | 3 | เปิด Console และเขียน script | จำลอง timestamp เก่า | [ ] | | 4 | Run script: | | | | ```javascript | | | | const stalePosition = { | | | | coords: { latitude: 13.7563, longitude: 100.5018, accuracy: 10 }, | | | | timestamp: Date.now() - 70000 // 70 seconds ago | | | | } | | | | navigator.geolocation.getCurrentPosition(pos => console.log(pos)) | | | | ``` | | | | 5 | รีเฟรชแอป | รับพิกัด | [ ] | | 6 | ตรวจสอบ validationResult | mockIndicators += 2 | [ ] | | 7 | ตรวจสอบ error message | "ข้อมูลตำแหน่งเก่าเกินไป กรุณารับสัญญาณ GPS ใหม่" | [ ] | **Verification Checklist:** - [ ] `validateTimestamp(staleTimestamp) = false` - [ ] `mockIndicators += 2` - [ ] แสดง error message ถูกต้อง --- #### Test Case: TC-LOC-03-05 - ความแม่นยำต่ำ (Poor accuracy) **Objective**: ทดสอบการตรวจสอบความแม่นยำต่ำ | Step | Action | Expected Result | Screenshot | |------|--------|-----------------|------------| | 1 | เปิด Chrome DevTools | F12 > Sensors | [ ] | | 2 | เลือก Custom Location | กำหนดพิกัด | [ ] | | 3 | เปิด Console และเขียน script | จำลอง accuracy ต่ำ | [ ] | | 4 | Run script: | | | | ```javascript | | | | const poorAccuracyPosition = { | | | | coords: { latitude: 13.7563, longitude: 100.5018, accuracy: 150 }, | | | | timestamp: Date.now() | | | | } | | | | ``` | | | | 5 | รีเฟรชแอป | รับพิกัด | [ ] | | 6 | ตรวจสอบ validationResult | warnings = ["ความแม่นยำตำแหน่งต่ำเกินไป..."] | [ ] | | 7 | ตรวจสอบ mockIndicators | mockIndicators += 1 | [ ] | **Verification Checklist:** - [ ] `validateAccuracy(150) = false` - [ ] `mockIndicators += 1` - [ ] แสดง warning message ถูกต้อง --- #### Test Case: TC-LOC-03-06 - ความเร็วเคลื่อนที่ผิดปกติ (Impossible speed) **Objective**: ทดสอบการตรวจสอบความเร็วเคลื่อนที่ผิดปกติ | Step | Action | Expected Result | Screenshot | |------|--------|-----------------|------------| | 1 | เปิดแอป HRMS ที่ตำแหน่ง A (13.7563, 100.5018) | รับพิกัด A | [ ] | | 2 | รอสักครู่เพื่อให้บันทึกตำแหน่ง A ลง history | previousPositions มีค่า | [ ] | | 3 | เปิด Fake GPS App | เปิดแอป | [ ] | | 4 | ตั้งค่าพิกัด B (15.8700, 100.9925) ที่ห่างกัน ~180 กม. | พิกัด B | [ ] | | 5 | รีเฟรชแอปทันที (ภายใน 60 วินาที) | รับพิกัด B | [ ] | | 6 | ตรวจสอบ Console (calculateSpeed) | speed = ~3000 km/h (> 100 m/s) | [ ] | | 7 | ตรวจสอบ validationResult | mockIndicators += 3 | [ ] | | 8 | ตรวจสอบ error message | "ตรวจพบการเคลื่อนที่ด้วยความเร็วผิดปกติ..." | [ ] | **Verification Checklist:** - [ ] `calculateSpeed()` = ความเร็ว > 100 m/s - [ ] `mockIndicators += 3` - [ ] แสดง error message ถูกต้อง --- ### 3.4 TC-LOC-04: Mock Location Detection Testing #### Test Case: TC-LOC-04-01 - ไม่พบ Mock Location (Normal GPS) **Objective**: ทดสอบการใช้งาน GPS ปกติ ไม่พบ mock location | Step | Action | Expected Result | Screenshot | |------|--------|-----------------|------------| | 1 | ตรวจสอบว่าปิด Fake GPS App | ไม่มี Fake GPS App ทำงาน | [ ] | | 2 | เปิดแอป HRMS | แสดงหน้าแรก | [ ] | | 3 | อนุญาต Location Permission | รับสิทธิ์สำเร็จ | [ ] | | 4 | กดปุ่มขอตำแหน่ง | เริ่มรับพิกัด GPS | [ ] | | 5 | รับพิกัดสำเร็จ | แสดงแผนที่ | [ ] | | 6 | ตรวจสอบ Console (validationResult) | { isValid: true, isMockDetected: false } | [ ] | | 7 | ตรวจสอบ locationGranted | locationGranted = true | [ ] | | 8 | ตรวจสอบ isMockLocationDetected | isMockLocationDetected = false | [ ] | | 9 | ตรวจสอบปุ่มลงเวลา | ปุ่มใช้งานได้ | [ ] | **Verification Checklist:** - [ ] `isValid = true` - [ ] `isMockDetected = false` - [ ] `locationGranted = true` - [ ] `isMockLocationDetected = false` - [ ] ปุ่มลงเวลาใช้งานได้ --- #### Test Case: TC-LOC-04-02 - พบ Mock Location - Fake GPS App **Objective**: ทดสอบการตรวจจับ mock location จาก Fake GPS App | Step | Action | Expected Result | Screenshot | |------|--------|-----------------|------------| | 1 | เปิด Fake GPS Location App | เปิดแอป | [ ] | | 2 | ตั้งค่าตำแหน่งปลอง (เช่น 13.7563, 100.5018) | ตั้งค่าสำเร็จ | [ ] | | 3 | เปิด Developer Options > Select mock location app | เลือก Fake GPS App | [ ] | | 4 | เปิดแอป HRMS | แสดงหน้าแรก | [ ] | | 5 | กดปุ่มขอตำแหน่ง | เริ่มรับพิกัด GPS | [ ] | | 6 | รับพิกัดจาก Fake GPS | แสดงพิกัดปลอง | [ ] | | 7 | ตรวจสอบ Console (validationResult) | isMockDetected = true | [ ] | | 8 | ตรวจสอบ mockIndicators | mockIndicators >= 3 | [ ] | | 9 | ตรวจสอบ error message | "ตรวจพบว่าตำแหน่ง GPS อาจไม่ถูกต้อง..." | [ ] | | 10 | ตรวจสอบ isMockLocationDetected | isMockLocationDetected = true | [ ] | | 11 | ตรวจสอบ disabledBtn | disabledBtn = true | [ ] | | 12 | พยายามกดปุ่มลงเวลา | กดไม่ได้ | [ ] | **Verification Checklist:** - [ ] `isMockDetected = true` - [ ] `mockIndicators >= 3` - [ ] แสดง error message ถูกต้อง - [ ] `isMockLocationDetected = true` - [ ] `disabledBtn = true` - [ ] ไม่สามารถลงเวลาได้ --- ### 3.5 TC-LOC-05: POI Resolution Testing #### Test Case: TC-LOC-05-01 - แปลงพิกัดเป็นชื่อสถานที่สำเร็จ (Bangkok GIS) **Objective**: ทดสอบการแปลงพิกัดเป็นชื่อสถานที่สำเร็จผ่าน Bangkok GIS API | Step | Action | Expected Result | Screenshot | |------|--------|-----------------|------------| | 1 | เปิดแอป HRMS | แสดงหน้าแรก | [ ] | | 2 | อนุญาต Location Permission | รับสิทธิ์สำเร็จ | [ ] | | 3 | กดปุ่มขอตำแหน่ง | เริ่มรับพิกัด GPS | [ ] | | 4 | รับพิกัดสำเร็จ | แสดงแผนที่ | [ ] | | 5 | เปิด Network Tab (DevTools) | แสดง requests | [ ] | | 6 | ตรวจสอบ request ไป Bangkok GIS | GET `https://bmagis.bangkok.go.th/...` | [ ] | | 7 | ตรวจสอบ response | status = 200, มี PlaceName | [ ] | | 8 | ตรวจสอบ poiPlaceName | poiPlaceName มีค่า | [ ] | | 9 | ตรวจสอบ formLocation.POI | formLocation.POI มีค่า | [ ] | | 10 | ตรวจสอบหน้าจอ | แสดงชื่อสถานที่ใกล้เคียง | [ ] | **Verification Checklist:** - [ ] เรียก Bangkok GIS API สำเร็จ - [ ] Response มี PlaceName - [ ] `poiPlaceName` มีค่า - [ ] แสดงชื่อสถานที่ใกล้เคียงถูกต้อง --- #### Test Case: TC-LOC-05-02 - แปลงพิกัดเป็นชื่อสถานที่สำเร็จ (ArcGIS Fallback) **Objective**: ทดสอบการแปลงพิกัดเป็นชื่อสถานที่สำเร็จผ่าน ArcGIS API (เมื่อ Bangkok GIS fail) | Step | Action | Expected Result | Screenshot | |------|--------|-----------------|------------| | 1 | เปิด Chrome DevTools > Network Tab | แสดง requests | [ ] | | 2 | เปิด Throttling > Offline | จำลอง Bangkok GIS down | [ ] | | 3 | เปิดแอป HRMS | แสดงหน้าแรก | [ ] | | 4 | อนุญาต Location Permission | รับสิทธิ์สำเร็จ | [ ] | | 5 | กดปุ่มขอตำแหน่ง | เริ่มรับพิกัด GPS | [ ] | | 6 | รับพิกัดสำเร็จ | แสดงแผนที่ | [ ] | | 7 | ปิด Throttling (กลับสู่ Online) | Bangkok GIS ยังไม่พร้อม | [ ] | | 8 | ตรวจสอบ Console | Bangkok GIS API fail | [ ] | | 9 | ตรวจสอบ fallback | เรียก ArcGIS API | [ ] | | 10 | ตรวจสอบ response | GET `https://geocode.arcgis.com/...` | [ ] | | 11 | ตรวจสอบ poiPlaceName | poiPlaceName มีค่า | [ ] | **Verification Checklist:** - [ ] Bangkok GIS API fail - [ ] Fallback ไป ArcGIS API สำเร็จ - [ ] `poiPlaceName` มีค่า - [ ] แสดงชื่อสถานที่ใกล้เคียง --- ### 3.6 TC-LOC-06: Check-in with Location Testing #### Test Case: TC-LOC-06-01 - ลงเวลาเข้าสำเร็จ - ณ สถานที่ตั้ง (In-place) **Objective**: ทดสอบการลงเวลาเข้าสำเร็จเมื่ออยู่ ณ สถานที่ตั้ง | Step | Action | Expected Result | Screenshot | |------|--------|-----------------|------------| | 1 | เปิดแอป HRMS | แสดงหน้าแรก | [ ] | | 2 | ตรวจสอบ statusCheckin | statusCheckin = true (เข้างาน) | [ ] | | 3 | อนุญาต Location Permission | รับสิทธิ์สำเร็จ | [ ] | | 4 | กดปุ่มขอตำแหน่ง | รับพิกัดสำเร็จ | [ ] | | 5 | ถ่ายรูปภาพ | แสดงรูปที่ถ่าย | [ ] | | 6 | เลือก "ในสถานที่" | workplace = 'in-place' | [ ] | | 7 | กด "ลงเวลาเข้างาน" | แสดง dialog ยืนยัน | [ ] | | 8 | ตรวจสอบ dialog message | "ยืนยันการลงเวลาเข้างาน ในสถานที่..." | [ ] | | 9 | กด "ยืนยัน" | ส่งข้อมูลไป API | [ ] | | 10 | เปิด Network Tab | POST `/leave/check-in` | [ ] | | 11 | ตรวจสอบ payload | { lat, lon, POI, isLocation: true, locationName: '', img, remark } | [ ] | | 12 | ตรวจสอบ response | status = 200 | [ ] | | 13 | ตรวจสอบ modal | แสดง modal ลงเวลาเข้างานสำเร็จ | [ ] | | 14 | ตรวจสอบ statusCheckin | statusCheckin = false | [ ] | **Verification Checklist:** - [ ] API call ถูกต้อง - [ ] Payload ถูกต้อง (isLocation: true, locationName: '') - [ ] Response status 200 - [ ] แสดง modal สำเร็จ - [ ] `statusCheckin = false` --- #### Test Case: TC-LOC-06-02 - ลงเวลาเข้าสำเร็จ - นอกสถานที่ตั้ง (Off-site) **Objective**: ทดสอบการลงเวลาเข้าสำเร็จเมื่ออยู่นอกสถานที่ตั้ง | Step | Action | Expected Result | Screenshot | |------|--------|-----------------|------------| | 1 | เปิดแอป HRMS | แสดงหน้าแรก | [ ] | | 2 | ตรวจสอบ statusCheckin | statusCheckin = true (เข้างาน) | [ ] | | 3 | อนุญาต Location Permission | รับสิทธิ์สำเร็จ | [ ] | | 4 | กดปุ่มขอตำแหน่ง | รับพิกัดสำเร็จ | [ ] | | 5 | ถ่ายรูปภาพ | แสดงรูปที่ถ่าย | [ ] | | 6 | เลือก "นอกสถานที่" | workplace = 'off-site' | [ ] | | 7 | เลือก "ปฏิบัติงานที่บ้าน (WFH)" | model = 'ปฏิบัติงานที่บ้าน (WFH)' | [ ] | | 8 | ตรวจสอบ useLocation | useLocation = 'ปฏิบัติงานที่บ้าน (WFH)' | [ ] | | 9 | กด "ลงเวลาเข้างาน" | แสดง dialog ยืนยัน | [ ] | | 10 | ตรวจสอบ dialog message | "ยืนยันการลงเวลาเข้างาน นอกสถานที่ (ปฏิบัติงานที่บ้าน (WFH))..." | [ ] | | 11 | กด "ยืนยัน" | ส่งข้อมูลไป API | [ ] | | 12 | เปิด Network Tab | POST `/leave/check-in` | [ ] | | 13 | ตรวจสอบ payload | { lat, lon, POI, isLocation: false, locationName: 'ปฏิบัติงานที่บ้าน (WFH)', img, remark } | [ ] | | 14 | ตรวจสอบ response | status = 200 | [ ] | **Verification Checklist:** - [ ] API call ถูกต้อง - [ ] Payload ถูกต้อง (isLocation: false, locationName มีค่า) - [ ] Response status 200 - [ ] แสดง modal สำเร็จ --- #### Test Case: TC-LOC-06-03 - ลงเวลาเข้าล้มเหลว - Mock Location detected **Objective**: ทดสอบการลงเวลาเข้าล้มเหลวเมื่อตรวจพบ mock location | Step | Action | Expected Result | Screenshot | |------|--------|-----------------|------------| | 1 | เปิด Fake GPS Location App | เปิดแอป | [ ] | | 2 | ตั้งค่าตำแหน่งปลอง | ตั้งค่าสำเร็จ | [ ] | | 3 | เปิดแอป HRMS | แสดงหน้าแรก | [ ] | | 4 | อนุญาต Location Permission | รับสิทธิ์สำเร็จ | [ ] | | 5 | กดปุ่มขอตำแหน่ง | เริ่มรับพิกัด GPS | [ ] | | 6 | รับพิกัดจาก Fake GPS | ตรวจจับ mock location | [ ] | | 7 | ตรวจสอบ error message | "ตรวจพบว่าตำแหน่ง GPS อาจไม่ถูกต้อง..." | [ ] | | 8 | ตรวจสอบ isMockLocationDetected | isMockLocationDetected = true | [ ] | | 9 | ตรวจสอบ disabledBtn | disabledBtn = true | [ ] | | 10 | ถ่ายรูปภาพ | แสดงรูปที่ถ่าย | [ ] | | 11 | พยายามกด "ลงเวลาเข้างาน" | กดไม่ได้ (ปุ่ม disabled) | [ ] | **Verification Checklist:** - [ ] ตรวจจับ mock location สำเร็จ - [ ] `isMockLocationDetected = true` - [ ] `disabledBtn = true` - [ ] ไม่สามารถลงเวลาเข้างานได้ --- ### 3.7 TC-LOC-07: Check-out with Location Testing #### Test Case: TC-LOC-07-01 - ลงเวลาออกสำเร็จ **Objective**: ทดสอบการลงเวลาออกสำเร็จพร้อมตำแหน่ง | Step | Action | Expected Result | Screenshot | |------|--------|-----------------|------------| | 1 | เปิดแอป HRMS | แสดงหน้าแรก | [ ] | | 2 | ตรวจสอบ statusCheckin | statusCheckin = false (ออกงาน) | [ ] | | 3 | อนุญาต Location Permission | รับสิทธิ์สำเร็จ | [ ] | | 4 | กดปุ่มขอตำแหน่ง | รับพิกัดสำเร็จ | [ ] | | 5 | ถ่ายรูปภาพ | แสดงรูปที่ถ่าย | [ ] | | 6 | กด "ลงเวลาออกงาน" | เรียก checkoutCheck API | [ ] | | 7 | เปิด Network Tab | GET `/leave/user/checkout-check/N` | [ ] | | 8 | ตรวจสอบ response | status = 'NORMAL' หรือ 'ABSENT' | [ ] | | 9 | ตรวจสอบ dialog | แสดง dialog ยืนยันการลงเวลาออกงาน | [ ] | | 10 | กด "ยืนยัน" | ส่งข้อมูลไป API | [ ] | | 11 | เปิด Network Tab | POST `/leave/check-in` | [ ] | | 12 | ตรวจสอบ payload | { lat, lon, POI, isLocation, locationName, img, remark, checkInId } | [ ] | | 13 | ตรวจสอบ response | status = 200 | [ ] | | 14 | ตรวจสอบ modal | แสดง modal ลงเวลาออกงานสำเร็จ | [ ] | | 15 | ตรวจสอบ statusCheckin | statusCheckin = true | [ ] | **Verification Checklist:** - [ ] checkoutCheck API ถูกต้อง - [ ] API call ถูกต้อง (มี checkInId) - [ ] Response status 200 - [ ] แสดง modal สำเร็จ - [ ] `statusCheckin = true` --- ### 3.8 TC-LOC-09: Privacy Consent Testing #### Test Case: TC-LOC-09-01 - แสดง Privacy Modal ก่อนใช้ Location **Objective**: ทดสอบการแสดง Privacy Modal ก่อนใช้ Location | Step | Action | Expected Result | Screenshot | |------|--------|-----------------|------------| | 1 | เปิดแอป HRMS ครั้งแรก (หรือ clear localStorage) | แสดงหน้าแรก | [ ] | | 2 | ตรวจสอบ privacyStore.isAccepted | isAccepted = false | [ ] | | 3 | กดปุ่มที่ต้องการ Location (แผนที่/กล้อง) | checkPrivacyAccepted() return false | [ ] | | 4 | ตรวจสอบ privacyStore.modalPrivacy | modalPrivacy = true | [ ] | | 5 | ตรวจสอบ Privacy Modal | แสดง Privacy Modal | [ ] | | 6 | ตรวจสอบว่าไม่สามารถใช้งาน Location ได้ | แผนที่/กล้องไม่ทำงาน | [ ] | **Verification Checklist:** - [ ] `isAccepted = false` - [ ] `modalPrivacy = true` - [ ] แสดง Privacy Modal - [ ] ไม่สามารถใช้งาน Location ได้ --- #### Test Case: TC-LOC-09-02 - ยอมรับ Privacy Policy **Objective**: ทดสอบการยอมรับ Privacy Policy | Step | Action | Expected Result | Screenshot | |------|--------|-----------------|------------| | 1 | เปิดแอป HRMS ครั้งแรก | แสดงหน้าแรก | [ ] | | 2 | แสดง Privacy Modal | แสดง Privacy Modal | [ ] | | 3 | กด "ยอมรับ" | เรียก privacyStore.setAccepted(true) | [ ] | | 4 | ตรวจสอบ privacyStore.isAccepted | isAccepted = true | [ ] | | 5 | ตรวจสอบ privacyStore.modalPrivacy | modalPrivacy = false | [ ] | | 6 | ตรวจสอบ Privacy Modal | Modal ปิด | [ ] | | 7 | กดปุ่มขอตำแหน่ง | เรียก mapRef.value?.requestLocationPermission() | [ ] | | 8 | อนุญาต Location Permission | รับสิทธิ์สำเร็จ | [ ] | | 9 | รับพิกัดสำเร็จ | แสดงแผนที่ | [ ] | **Verification Checklist:** - [ ] `isAccepted = true` - [ ] `modalPrivacy = false` - [ ] Modal ปิด - [ ] สามารถใช้งาน Location ได้ --- #### Test Case: TC-LOC-09-03 - ปฏิเสธ Privacy Policy **Objective**: ทดสอบการปฏิเสธ Privacy Policy | Step | Action | Expected Result | Screenshot | |------|--------|-----------------|------------| | 1 | เปิดแอป HRMS ครั้งแรก | แสดงหน้าแรก | [ ] | | 2 | แสดง Privacy Modal | แสดง Privacy Modal | [ ] | | 3 | กด "ปฏิเสธ" หรือปิด Modal | เรียก privacyStore.modalPrivacy = false | [ ] | | 4 | ตรวจสอบ privacyStore.isAccepted | isAccepted = false | [ ] | | 5 | ตรวจสอบ privacyStore.modalPrivacy | modalPrivacy = false | [ ] | | 6 | ตรวจสอบ Privacy Modal | Modal ปิด | [ ] | | 7 | กดปุ่มขอตำแหน่ง | checkPrivacyAccepted() return false | [ ] | | 8 | ตรวจสอบ | Privacy Modal แสดงอีกครั้ง | [ ] | **Verification Checklist:** - [ ] `isAccepted = false` - [ ] `modalPrivacy = false` - [ ] Modal ปิด - [ ] ไม่สามารถใช้งาน Location ได้ - [ ] แจ้งเตือนเมื่อพยายามใช้งาน Location --- ## 4. Mock Location Testing ### 4.1 Fake GPS Apps for Testing #### 4.1.1 Android Fake GPS Apps | App Name | Link | Features | |----------|------|----------| | Fake GPS Location | [Play Store](https://play.google.com/store/apps/details?id=com.lexa.fakegps) | Simple location spoofing | | GPS Joystick | [Play Store](https://play.google.com/store/apps/details?id=com.theappninjas.android.gpsjoke) | Joystick control, route simulation | | Mock GPS | [Play Store](https://play.google.com/store/apps/details?id=com.incorporateapps.fakegps) | Multiple location saving | #### 4.1.2 iOS Fake GPS Apps | App Name | Link | Features | |----------|------|----------| | Location Changer | [App Store](https://apps.apple.com/app/location-changer/id1383869695) | Location spoofing (needs jailbreak) | | Xcode Simulation | - | Built-in location simulation | ### 4.2 Mock Location Test Scenarios #### Scenario 1: Basic Mock Location 1. **Setup** - เปิด Fake GPS Location App - ตั้งค่าตำแหน่ง: 13.7563, 100.5018 (Sanam Suea Pa) - ตั้งค่าความแม่นยำ: 10 meters 2. **Execute** - เปิดแอป HRMS - กดปุ่มขอตำแหน่ง - ตรวจสอบผลลัพธ์ 3. **Expected** - ตรวจจับ mock location (indicators >= 3) - แสดง error message - ปุ่มลงเวลา disabled #### Scenario 2: Rapid Location Change 1. **Setup** - เปิดแอป HRMS ที่ตำแหน่ง A (13.7563, 100.5018) - รอสักครู่เพื่อให้บันทึกตำแหน่ง A ลง history 2. **Execute** - เปิด Fake GPS App - เปลี่ยนตำแหน่งไป B (15.8700, 100.9925) - รีเฟรชแอป HRMS ทันที (ภายใน 60 วินาที) 3. **Expected** - คำนวณความเร็ว = ~3000 km/h (> 100 m/s) - mockIndicators += 3 - แสดง error: "ตรวจพบการเคลื่อนที่ด้วยความเร็วผิดปกติ..." #### Scenario 3: Null Island (0,0) 1. **Setup** - เปิด Fake GPS App - ตั้งค่าตำแหน่ง: 0, 0 (Null Island) 2. **Execute** - เปิดแอป HRMS - กดปุ่มขอตำแหน่ง 3. **Expected** - validateCoordinates(0, 0) = false - mockIndicators += 3 - แสดง error: "พิกัดตำแหน่งไม่ถูกต้อง กรุณาลองใหม่" --- ## 5. Developer Tools Testing ### 5.1 Chrome DevTools Sensor Simulation #### 5.1.1 Enable Sensors 1. เปิด Chrome DevTools (F12) 2. เลือก More tools > Sensors 3. ตั้งค่า Location #### 5.1.2 Pre-defined Locations | Location | Latitude | Longitude | Use Case | |----------|----------|-----------|----------| | Sanam Suea Pa | 13.7563 | 100.5018 | Bangkok office | | Suvarnabhumi Airport | 13.6900 | 100.7501 | Outdoor high accuracy | | Central World | 13.7944 | 100.5439 | Indoor | | Null Island | 0 | 0 | Invalid coordinates | | Out of Range | 91 | 181 | Out of range test | #### 5.1.3 Custom Location 1. เลือก "Other..." ใน Sensors tab 2. ป้อน Latitude และ Longitude 3. กด Enter ### 5.2 Network Throttling #### 5.2.1 Enable Throttling 1. เปิด Chrome DevTools (F12) 2. เลือก Network tab 3. เลือก Throttling 4. เลือก preset หรือ custom #### 5.2.2 Throttling Presets | Preset | Download | Upload | Latency | Use Case | |--------|----------|--------|---------|----------| | Offline | 0 | 0 | - | API failure test | | Slow 3G | 500 Kbps | 500 Kbps | 2000ms | Slow network | | Fast 3G | 1.6 Mbps | 750 Kbps | 100ms | Normal mobile | ### 5.3 Console Testing #### 5.3.1 Test Location Validation ```javascript // Test 1: Valid coordinates const validPosition = { coords: { latitude: 13.7563, longitude: 100.5018, accuracy: 10 }, timestamp: Date.now() } console.log(validateLocation(validPosition)) // Expected: { isValid: true, isMockDetected: false } // Test 2: Invalid coordinates (0,0) const invalidPosition = { coords: { latitude: 0, longitude: 0, accuracy: 10 }, timestamp: Date.now() } console.log(validateLocation(invalidPosition)) // Expected: { isValid: false, isMockDetected: true, confidence: 'high' } // Test 3: Stale timestamp const stalePosition = { coords: { latitude: 13.7563, longitude: 100.5018, accuracy: 10 }, timestamp: Date.now() - 70000 // 70 seconds ago } console.log(validateLocation(stalePosition)) // Expected: errors = ["ข้อมูลตำแหน่งเก่าเกินไป..."] // Test 4: Poor accuracy const poorAccuracyPosition = { coords: { latitude: 13.7563, longitude: 100.5018, accuracy: 150 }, timestamp: Date.now() } console.log(validateLocation(poorAccuracyPosition)) // Expected: warnings = ["ความแม่นยำตำแหน่งต่ำเกินไป..."] ``` #### 5.3.2 Test Distance Calculation ```javascript // Test haversineDistance const distance = haversineDistance(13.7563, 100.5018, 15.8700, 100.9925) console.log(`Distance: ${distance} meters`) // Expected: ~180,000 meters (180 km) // Test speed calculation const pos1 = { latitude: 13.7563, longitude: 100.5018, timestamp: Date.now() - 60000 } const pos2 = { latitude: 15.8700, longitude: 100.9925, timestamp: Date.now() } const speed = calculateSpeed(pos1, pos2) console.log(`Speed: ${speed} m/s (${speed * 3.6} km/h)`) // Expected: ~3000 km/h (> 100 m/s = 360 km/h) ``` --- ## 6. Device-Specific Testing ### 6.1 Mobile Device Testing #### 6.1.1 Android Testing | Step | Action | Notes | |------|--------|-------| | 1 | Install Fake GPS App | Google Play Store | | 2 | Enable Developer Options | Settings > About Phone > Build Number (7 taps) | | 3 | Enable Mock Location | Settings > Developer Options > Select mock location app | | 4 | Set Fake Location | Fake GPS App > Set Location | | 5 | Open HRMS App | Test mock detection | #### 6.1.2 iOS Testing | Step | Action | Notes | |------|--------|-------| | 1 | Connect iPhone to Mac | USB cable | | 2 | Open Xcode | Mac | | 3 | Select Device > Debug Location | Xcode menu | | 4 | Set Custom Location | Enter lat/lon | | 5 | Open HRMS App | Test mock detection | ### 6.2 Desktop Browser Testing #### 6.2.1 Chrome Testing | Step | Action | Notes | |------|--------|-------| | 1 | Open Chrome | - | | 2 | Open DevTools | F12 | | 3 | More tools > Sensors | - | | 4 | Set Location | Choose or custom | | 5 | Open HRMS App | Test location | #### 6.2.2 Edge Testing | Step | Action | Notes | |------|--------|-------| | 1 | Open Edge | - | | 2 | Open DevTools | F12 | | 3 | More tools > Sensors | - | | 4 | Set Location | Choose or custom | | 5 | Open HRMS App | Test location | --- ## 7. Test Data & Scenarios ### 7.1 Valid Locations | Name | Latitude | Longitude | Accuracy | Expected | |------|----------|-----------|----------|----------| | Sanam Suea Pa | 13.7563 | 100.5018 | <= 100m | Pass | | Suvarnabhumi | 13.6900 | 100.7501 | <= 100m | Pass | | Central World | 13.7944 | 100.5439 | <= 100m | Pass | | Chiang Mai | 18.7883 | 98.9853 | <= 100m | Pass | ### 7.2 Invalid Locations | Name | Latitude | Longitude | Accuracy | Expected | |------|----------|-----------|----------|----------| | Null Island | 0 | 0 | Any | Fail (invalid coordinates) | | Out of Range (lat) | 91 | 100.5018 | Any | Fail (invalid coordinates) | | Out of Range (lon) | 13.7563 | 181 | Any | Fail (invalid coordinates) | | NaN | NaN | NaN | Any | Fail (invalid coordinates) | ### 7.3 Edge Cases | Scenario | Latitude | Longitude | Accuracy | Timestamp | Expected | |----------|----------|-----------|----------|-----------|----------| | Stale Data | 13.7563 | 100.5018 | 10 | t - 70s | Fail (stale) | | Poor Accuracy | 13.7563 | 100.5018 | 150 | current | Warning | | Impossible Speed | 15.8700 | 100.9925 | 10 | t + 60s (from 13.7563, 100.5018) | Fail (speed) | --- ## 8. Troubleshooting ### 8.1 Common Issues | Issue | Cause | Solution | |-------|-------|----------| | ไม่ได้รับพิกัด GPS | GPS ปิดอยู่ | เปิด Location Service | | แผนที่ไม่แสดง | ยังไม่ยอมรับ Privacy Policy | ยอมรับ Privacy Policy | | ปุ่มลงเวลา disabled | Mock location detected | ปิด Fake GPS App และรีเฟรช | | POI ไม่แสดง | Bangkok GIS down | รอ fallback ไป ArcGIS | | ความแม่นยำต่ำ | อยู่ในอาคาร | ไปยังพื้นที่เปิดกว้าง | ### 8.2 Debug Mode #### Enable Debug Mode 1. เปิด Console ใน Browser 2. ตรวจสอบค่าต่าง ๆ: ```javascript // Check validation result console.log('Validation:', validationResult) // Check location granted console.log('Location Granted:', locationGranted) // Check mock detected console.log('Mock Detected:', isMockLocationDetected) // Check form location console.log('Form Location:', formLocation) // Check privacy accepted console.log('Privacy Accepted:', privacyStore.isAccepted) ``` --- ## 9. Test Execution Checklist ### 9.1 Pre-Test Checklist - [ ] ติดตั้ง Fake GPS App (สำหรับการทดสอบ mock location) - [ ] เปิด Developer Options (Android) หรือเตรียม Xcode (iOS) - [ ] เตรียม Test Data และ Test Scenarios - [ ] เตรียม Screenshot/Screen Recording tool - [ ] ตรวจสอบ Test Environment (Network, GPS, etc.) ### 9.2 During Test Checklist - [ ] บันทึกผลลัพธ์ทุก Test Case - [ ] ถ่าย Screenshot สำคัญ - [ ] บันทึกข้อผิดพลาดที่พบ - [ ] ตรวจสอบ Console logs - [ ] ตรวจสอบ Network requests ### 9.3 Post-Test Checklist - [ ] สรุปผลการทดสอบ - [ ] รายงาน bugs ที่พบ - [ ] อัปเดต Test Cases document - [ ] เตรียม Test Evidence (Screenshots, Videos) - [ ] ส่งรายงานให้ทีมที่เกี่ยวข้อง --- ## 10. References ### 10.1 Related Documents - [Test Cases: Location Features](./test-cases-location.md) - [Location Validation Logic](../src/composables/useLocationValidation.ts) - [Home View Component](../src/views/HomeView.vue) - [AscGISMap Component](../src/components/AscGISMap.vue) ### 10.2 External Resources - [W3C Geolocation API](https://www.w3.org/TR/geolocation-API/) - [MDN Geolocation API](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API) - [Chrome DevTools Sensors](https://developer.chrome.com/docs/devtools/device-mode/override-device-metrics/) --- ## 11. Revision History | Version | Date | Author | Changes | |---------|------|--------|---------| | 1.0.0 | 2025-03-09 | QA Team | Initial version - Detailed test steps for Location features | --- ## 12. Approval | Role | Name | Signature | Date | |------|------|-----------|------| | QA Lead | | | | | Developer | | | | | Product Owner | | | |