# 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 | | | |
