{"id":30133924,"url":"https://github.com/rezapace/parent-axes","last_synced_at":"2025-08-10T20:37:01.178Z","repository":{"id":305995143,"uuid":"1024635465","full_name":"rezapace/Parent-Axes","owner":"rezapace","description":"Parent-Axes","archived":false,"fork":false,"pushed_at":"2025-07-23T03:00:14.000Z","size":20031,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-07-23T05:12:49.048Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rezapace.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-23T02:57:34.000Z","updated_at":"2025-07-23T02:59:41.000Z","dependencies_parsed_at":"2025-07-23T05:12:53.814Z","dependency_job_id":"5ee17333-83f4-4f5d-a19c-f3798731c92b","html_url":"https://github.com/rezapace/Parent-Axes","commit_stats":null,"previous_names":["rezapace/parent-axes"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/rezapace/Parent-Axes","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rezapace%2FParent-Axes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rezapace%2FParent-Axes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rezapace%2FParent-Axes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rezapace%2FParent-Axes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rezapace","download_url":"https://codeload.github.com/rezapace/Parent-Axes/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rezapace%2FParent-Axes/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269784719,"owners_count":24475448,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-10T02:00:08.965Z","response_time":71,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-08-10T20:37:00.476Z","updated_at":"2025-08-10T20:37:01.129Z","avatar_url":"https://github.com/rezapace.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🎯 XPath Generator - Preceding/Following Specialist\n\n## 📖 Deskripsi\n\nXPath Generator adalah aplikasi web canggih yang dirancang khusus untuk menghasilkan pattern XPath yang fokus pada navigasi **Preceding** dan **Following** untuk testing iOS dan Android. Aplikasi ini sangat berguna untuk automation testing yang memerlukan navigasi element berdasarkan posisi relatif dalam DOM structure.\n\n## 🎬 Demo\n\n![XPath Generator Demo](doc/demo.gif)\n\n*Demo penggunaan XPath Generator untuk menganalisis XML dan menghasilkan pattern navigation*\n\n## ✨ Fitur Utama\n\n- 🔍 **XML Analysis**: Parsing dan analisis struktur XML secara mendalam\n- 🎯 **Advanced Pattern Generation**: Menghasilkan berbagai pattern XPath dengan confidence rating\n- 📱 **iOS/Android Support**: Konversi otomatis ke Groovy constants untuk testing framework\n- 📊 **Statistics \u0026 Analytics**: Laporan statistik lengkap tentang struktur XML\n- 🎨 **Modern UI**: Interface yang responsive dan user-friendly\n- 📋 **Copy to Clipboard**: One-click copy untuk semua pattern yang dihasilkan\n\n## 🚀 Cara Menjalankan\n\n```bash\n# Clone repository\ngit clone \u003crepository-url\u003e\ncd precidingsiblinggenerator\n\n# Build aplikasi\ngo build -o xpath_generator main.go\n\n# Jalankan aplikasi\n./xpath_generator\n```\n\nAplikasi akan berjalan di `http://localhost:8080`\n\n## 📚 Pattern XPath Navigation\n\n### 1. 🔙 **Preceding**\n\n**Preceding** mengacu pada semua element yang muncul **sebelum** element saat ini dalam document order (urutan dokumen).\n\n#### Karakteristik:\n- Mencakup semua element yang telah diproses sebelum element target\n- Tidak terbatas pada sibling, tetapi seluruh dokumen\n- Urutan berdasarkan document order, bukan tree hierarchy\n\n#### Contoh Pattern:\n```xpath\n// Basic preceding\n${element.xpath}/preceding::*[1]\n\n// Preceding by type\n${element.xpath}/preceding::XCUIElementTypeButton[1]\n\n// Preceding with condition\n${element.xpath}/preceding::*[@name='Login'][1]\n```\n\n#### Use Cases:\n- ✅ Mencari label atau instruksi yang muncul sebelum form field\n- ✅ Navigasi ke element yang sudah diproses sebelumnya\n- ✅ Validasi sequence dalam workflow\n\n#### 🎯 Kapan Menggunakan Preceding:\n- **Form Validation**: Ketika perlu mencari error message yang muncul sebelum input field\n- **Navigation Flow**: Untuk kembali ke step sebelumnya dalam multi-step form\n- **Context Reference**: Mencari heading atau label yang memberikan context untuk element saat ini\n- **Sequential Testing**: Validasi bahwa element muncul dalam urutan yang benar\n\n**Contoh Real Case**: \n```groovy\n// Mencari error message yang muncul sebelum password field\ndef errorMsg = driver.findElement(By.xpath(\"${passwordField.xpath}/preceding::*[contains(text(),'Password required')][1]\"))\n```\n\n---\n\n### 2. ⬅️ **Preceding Sibling**\n\n**Preceding Sibling** mengacu pada element yang memiliki **parent yang sama** dan muncul **sebelum** element saat ini.\n\n#### Karakteristik:\n- Hanya element dengan parent yang sama (sibling)\n- Lebih spesifik dan terbatas dibanding preceding\n- Ideal untuk navigasi dalam container yang sama\n\n#### Contoh Pattern:\n```xpath\n// Immediate preceding sibling\n${element.xpath}/preceding-sibling::*[1]\n\n// Preceding sibling by type\n${element.xpath}/preceding-sibling::XCUIElementTypeTextField[1]\n\n// All preceding siblings\n${element.xpath}/preceding-sibling::*\n```\n\n#### Use Cases:\n- ✅ Navigasi antar field dalam form yang sama\n- ✅ Mencari element sebelumnya dalam list atau menu\n- ✅ Validasi urutan element dalam container\n\n#### 🎯 Kapan Menggunakan Preceding Sibling:\n- **Form Navigation**: Berpindah dari field saat ini ke field sebelumnya dalam form\n- **List Item Selection**: Memilih item sebelumnya dalam list atau menu dropdown\n- **Tab Navigation**: Navigasi ke tab sebelumnya dalam tab container\n- **Button Grouping**: Mencari tombol yang berdekatan dalam button group\n\n**Contoh Real Case**:\n```groovy\n// Klik tombol \"Previous\" yang berada sebelum tombol \"Next\"\ndef previousBtn = driver.findElement(By.xpath(\"${nextButton.xpath}/preceding-sibling::*[contains(@name,'Previous')][1]\"))\npreviousBtn.click()\n```\n\n#### 🔧 Perbedaan Preceding vs Preceding Sibling:\n| Aspect | Preceding | Preceding Sibling |\n|--------|-----------|-------------------|\n| **Scope** | Seluruh dokumen | Hanya sibling dalam parent yang sama |\n| **Performance** | Lebih lambat | Lebih cepat |\n| **Precision** | Lebih luas | Lebih spesifik |\n| **Use Case** | Cross-container navigation | Same-container navigation |\n\n---\n\n### 3. 🔜 **Following**\n\n**Following** mengacu pada semua element yang muncul **setelah** element saat ini dalam document order.\n\n#### Karakteristik:\n- Mencakup semua element yang akan diproses setelah element target\n- Tidak terbatas pada sibling, tetapi seluruh dokumen\n- Berguna untuk navigasi forward dalam workflow\n\n#### Contoh Pattern:\n```xpath\n// Basic following\n${element.xpath}/following::*[1]\n\n// Following by type\n${element.xpath}/following::XCUIElementTypeButton[1]\n\n// Following with condition\n${element.xpath}/following::*[text()='Submit'][1]\n```\n\n#### Use Cases:\n- ✅ Navigasi ke step selanjutnya dalam wizard\n- ✅ Mencari element konfirmasi setelah input\n- ✅ Validasi element yang muncul setelah action\n\n#### 🎯 Kapan Menggunakan Following:\n- **Wizard Navigation**: Melanjutkan ke step berikutnya setelah mengisi form\n- **Confirmation Check**: Mencari pesan konfirmasi yang muncul setelah submit\n- **Dynamic Content**: Menunggu element yang muncul setelah loading atau action\n- **Validation Messages**: Mencari success/error message yang muncul setelah form submission\n\n**Contoh Real Case**:\n```groovy\n// Mencari success message yang muncul setelah login form\ndef successMsg = driver.findElement(By.xpath(\"${loginForm.xpath}/following::*[contains(text(),'Login successful')][1]\"))\nassert successMsg.isDisplayed()\n```\n\n---\n\n### 4. ➡️ **Following Sibling**\n\n**Following Sibling** mengacu pada element yang memiliki **parent yang sama** dan muncul **setelah** element saat ini.\n\n#### Karakteristik:\n- Hanya element dengan parent yang sama (sibling)\n- Lebih spesifik dan terbatas dibanding following\n- Ideal untuk navigasi sequential dalam container\n\n#### Contoh Pattern:\n```xpath\n// Immediate following sibling\n${element.xpath}/following-sibling::*[1]\n\n// Following sibling by type\n${element.xpath}/following-sibling::XCUIElementTypeButton[1]\n\n// All following siblings\n${element.xpath}/following-sibling::*\n```\n\n#### Use Cases:\n- ✅ Navigasi ke field berikutnya dalam form\n- ✅ Mencari tombol action setelah input field\n- ✅ Validasi sequence dalam list item\n\n#### 🎯 Kapan Menggunakan Following Sibling:\n- **Sequential Form Filling**: Berpindah ke field berikutnya setelah mengisi field saat ini\n- **Action Button Location**: Mencari tombol submit/save yang berada setelah input field\n- **List Navigation**: Navigasi ke item berikutnya dalam list yang sama\n- **Related Controls**: Mencari control yang berhubungan langsung (checkbox setelah label)\n\n**Contoh Real Case**:\n```groovy\n// Setelah mengisi username, lanjut ke password field\ndef passwordField = driver.findElement(By.xpath(\"${usernameField.xpath}/following-sibling::*[@type='password'][1]\"))\npasswordField.sendKeys(\"mypassword\")\n```\n\n#### 🔧 Perbedaan Following vs Following Sibling:\n| Aspect | Following | Following Sibling |\n|--------|-----------|-------------------|\n| **Timing** | Setelah action/loading | Immediate navigation |\n| **Context** | Document-wide search | Container-specific |\n| **Reliability** | Depends on timing | More predictable |\n| **Speed** | Slower (broader search) | Faster (limited scope) |\n\n---\n\n### 5. 🎯 **Last**\n\n**Last** mengacu pada element **terakhir** dari jenis tertentu dalam dokumen atau context tertentu.\n\n#### Karakteristik:\n- Menggunakan XPath function `last()`\n- Berguna untuk menemukan element final dalam list\n- Dapat dikombinasikan dengan condition untuk specificity\n\n#### Contoh Pattern:\n```xpath\n// Last element of type\n(//${IOS_TYPE_BUTTON})[last()]\n\n// Last with condition\n(//${IOS_TYPE_CELL}[@name='Item'])[last()]\n\n// Last in parent context\n(${parent.xpath}/${IOS_TYPE_TEXTFIELD})[last()]\n```\n\n#### Use Cases:\n- ✅ Scroll ke item terakhir dalam list\n- ✅ Navigasi ke footer element\n- ✅ Validasi element terakhir yang ditambahkan\n\n#### 🎯 Kapan Menggunakan Last:\n- **List Operations**: Scroll ke bottom untuk melihat item terbaru atau terakhir\n- **Data Validation**: Memverifikasi bahwa item baru ditambahkan di akhir list\n- **Navigation to End**: Langsung ke element terakhir tanpa iterasi\n- **Form Completion**: Mencari tombol submit yang biasanya di akhir form\n\n**Contoh Real Case**:\n```groovy\n// Scroll ke item terakhir dalam shopping cart untuk melihat total\ndef lastItem = driver.findElement(By.xpath(\"(//XCUIElementTypeCell)[last()]\"))\ndef totalPrice = driver.findElement(By.xpath(\"(//XCUIElementTypeStaticText[contains(@name,'Total')])[last()]\"))\n```\n\n#### 🎯 Advanced Last Pattern Usage:\n- **`[last()]`**: Element terakhir dari type tertentu\n- **`[last()-1]`**: Element kedua dari akhir  \n- **`[position()=last()]`**: Sama dengan `[last()]` tapi lebih eksplisit\n- **`[last()][contains(@name,'Submit')]`**: Element terakhir dengan kondisi tertentu\n\n**Performance Tips**:\n- ✅ `last()` lebih cepat dari iterasi manual\n- ✅ Kombinasikan dengan type selector untuk precision\n- ✅ Gunakan parent context untuk scope yang lebih sempit\n\n---\n\n---\n\n## 🎯 Decision Matrix: Kapan Menggunakan Pattern Mana?\n\n### 📊 Quick Reference Guide\n\n| Scenario | Pattern | Why | Example |\n|----------|---------|-----|---------|\n| **Form field → next field** | Following Sibling | Same container, predictable | Username → Password |\n| **Form field → previous field** | Preceding Sibling | Same container, rollback | Password → Username |\n| **After submit → success message** | Following | Cross-container, timing-based | Form → Confirmation |\n| **Error state → related field** | Preceding | Context lookup | Error → Input field |\n| **Navigate to end of list** | Last | Direct access, no iteration | → Bottom item |\n\n### 🚦 Decision Tree\n\n```\nNeed to navigate from current element?\n│\n├─ YES → Where to go?\n│   │\n│   ├─ Same container (parent)?\n│   │   ├─ Previous element → Use PRECEDING SIBLING\n│   │   └─ Next element → Use FOLLOWING SIBLING\n│   │\n│   ├─ Different container?\n│   │   ├─ Before current → Use PRECEDING  \n│   │   └─ After current → Use FOLLOWING\n│   │\n│   └─ Final element of type?\n│       └─ Use LAST\n│\n└─ NO → Use standard locator patterns\n```\n\n### ⚡ Performance Comparison\n\n| Pattern | Speed | Reliability | Scope | Best For |\n|---------|-------|-------------|-------|----------|\n| **Preceding Sibling** | ⚡⚡⚡⚡⚡ | ⭐⭐⭐⭐⭐ | Narrow | Form navigation |\n| **Following Sibling** | ⚡⚡⚡⚡⚡ | ⭐⭐⭐⭐⭐ | Narrow | Sequential flow |\n| **Preceding** | ⚡⚡⚡ | ⭐⭐⭐ | Wide | Context lookup |\n| **Following** | ⚡⚡⚡ | ⭐⭐⭐ | Wide | Result validation |\n| **Last** | ⚡⚡⚡⚡ | ⭐⭐⭐⭐ | Targeted | End navigation |\n\n## 🔄 Pattern Advanced\n\n### Relative Patterns\nPattern yang menggunakan context relationship:\n- **Parent-Child**: `${parent.xpath}/XCUIElementTypeButton`\n- **Depth-based**: `//*[@depth='3']/XCUIElementTypeCell`\n- **Index-based**: `(//XCUIElementTypeButton)[2]`\n\n### Conditional Patterns\nPattern dengan kondisi spesifik:\n- **Contains**: `//XCUIElementTypeButton[contains(@name, 'Save')]`\n- **Starts-with**: `//XCUIElementTypeTextField[starts-with(@name, 'Input')]`\n- **Position**: `//XCUIElementTypeCell[position()=2]`\n\n## 📱 iOS Testing Integration\n\nAplikasi ini secara otomatis mengkonversi element type ke Groovy constants:\n\n```groovy\n// iOS Element Types\nXCUIElementTypeButton → ${Constants.IOS_TYPE_BUTTON}\nXCUIElementTypeTextField → ${Constants.IOS_TYPE_TEXTFIELD}\nXCUIElementTypeStaticText → ${Constants.IOS_TYPE_STATIC_TEXT}\n\n// iOS Attributes\n@name → @${Constants.IOS_ATTR_NAME}\n@label → @${Constants.IOS_ATTR_LABEL}\n@value → @${Constants.IOS_ATTR_VALUE}\n```\n\n## 💡 Real-World Testing Examples\n\n### 🔐 Login Form Automation\n```groovy\n// Test flow: Username → Password → Login Button → Success Message\nclass LoginTest {\n    def testLoginFlow() {\n        // Fill username\n        def usernameField = findElement(\"//XCUIElementTypeTextField[@name='username']\")\n        usernameField.sendKeys(\"testuser\")\n        \n        // Navigate to password (following sibling)\n        def passwordField = findElement(\"${usernameField.xpath}/following-sibling::XCUIElementTypeSecureTextField[1]\")\n        passwordField.sendKeys(\"password123\")\n        \n        // Find login button (following sibling)\n        def loginBtn = findElement(\"${passwordField.xpath}/following-sibling::XCUIElementTypeButton[1]\")\n        loginBtn.click()\n        \n        // Verify success message (following - cross container)\n        def successMsg = findElement(\"${loginBtn.xpath}/following::*[contains(@name,'Welcome')][1]\")\n        assert successMsg.isDisplayed()\n    }\n}\n```\n\n### 🛒 Shopping Cart Operations\n```groovy\n// Navigate through cart items and validate total\nclass CartTest {\n    def testCartTotal() {\n        // Add items to cart first...\n        \n        // Navigate to last item to see total\n        def lastCartItem = findElement(\"(//XCUIElementTypeCell[contains(@name,'cart-item')])[last()]\")\n        \n        // Find total price (following the last item)\n        def totalPrice = findElement(\"${lastCartItem.xpath}/following::*[contains(@name,'Total')][1]\")\n        \n        // Validate total is correct\n        assert totalPrice.text.contains(\"$99.99\")\n    }\n}\n```\n\n### 📋 Form Validation Testing\n```groovy\n// Test form validation messages\nclass FormValidationTest {\n    def testFieldValidation() {\n        def emailField = findElement(\"//XCUIElementTypeTextField[@name='email']\")\n        emailField.sendKeys(\"invalid-email\")\n        \n        // Trigger validation\n        def submitBtn = findElement(\"//XCUIElementTypeButton[@name='submit']\")\n        submitBtn.click()\n        \n        // Find error message (typically appears after the field)\n        def errorMsg = findElement(\"${emailField.xpath}/following::*[contains(@name,'Invalid email')][1]\")\n        assert errorMsg.isDisplayed()\n        \n        // Or find error icon (typically preceding the field)\n        def errorIcon = findElement(\"${emailField.xpath}/preceding-sibling::*[@name='error-icon'][1]\")\n        assert errorIcon.isDisplayed()\n    }\n}\n```\n\n## 🤖 Android Testing Integration\n\nSupport untuk Android element types:\n\n```groovy\n// Android Element Types\nandroid.widget.Button → ${Constants.ANDROID_TYPE_BUTTON}\nandroid.widget.TextView → ${Constants.ANDROID_TYPE_TEXTVIEW}\nandroid.widget.EditText → ${Constants.ANDROID_TYPE_EDITTEXT}\n\n// Android Attributes\n@text → @${Constants.ANDROID_ATTR_TEXT}\n@content-desc → @${Constants.ANDROID_ATTR_CONTENT_DESC}\n@resource-id → @${Constants.ANDROID_ATTR_RESOURCE_ID}\n```\n\n## 📊 Confidence Rating System\n\nSetiap pattern dilengkapi dengan confidence rating (1-5 stars):\n\n- ⭐ **1 Star**: Pattern umum, mungkin tidak stabil\n- ⭐⭐ **2 Stars**: Pattern cukup reliable\n- ⭐⭐⭐ **3 Stars**: Pattern good, recommended untuk use case tertentu\n- ⭐⭐⭐⭐ **4 Stars**: Pattern very reliable, highly recommended\n- ⭐⭐⭐⭐⭐ **5 Stars**: Pattern excellent, sangat stabil dan unique\n\n## 🎨 UI Features\n\n### Home Page\n- 📊 **Statistics Dashboard**: Total elements, patterns generated, depth analysis\n- 📝 **XML Input**: Paste dan analyze XML content\n- 🏷️ **Element Cards**: Preview semua element dengan attributes\n\n### Analysis Page\n- 🔍 **Element Details**: Informasi lengkap element yang dipilih\n- 📋 **Pattern Categories**: Grouped by pattern type dengan color coding\n- 💡 **Use Cases**: Penjelasan kapan menggunakan setiap pattern\n- 🏷️ **Test Object ID**: Suggested variable names untuk automation\n- 📋 **One-Click Copy**: Copy pattern ke clipboard dengan hover effect\n\n### Responsive Design\n- 📱 **Mobile Friendly**: Layout responsif untuk semua device\n- 🎨 **Modern Styling**: Gradient backgrounds, hover effects, animations\n- 📜 **Horizontal Scroll**: Auto scroll untuk pattern yang panjang\n- 🎯 **Visual Indicators**: Color-coded patterns dan confidence badges\n\n## 🛠️ Technical Stack\n\n- **Backend**: Go (Golang) dengan standard library\n- **Frontend**: HTML5, CSS3, Vanilla JavaScript\n- **XML Processing**: Go xml package dengan custom parsing\n- **Template Engine**: Go html/template\n- **HTTP Server**: Go net/http\n\n## 📝 Struktur Project\n\n```\nprecidingsiblinggenerator/\n├── main.go              # Main application file\n├── go.mod              # Go module definition\n├── README.md           # Documentation\n├── rule.md             # iOS constants reference\n└── xmlfiles/           # Sample XML files\n    ├── login_2025-07-16_16-08-31_060030.xml\n    └── sample_ios.xml\n```\n\n## 🔧 Development\n\n### Prerequisites\n- Go 1.23.6 atau lebih baru\n- Browser modern (Chrome, Firefox, Safari, Edge)\n\n### Build \u0026 Run\n```bash\n# Development mode\ngo run main.go\n\n# Production build\ngo build -o xpath_generator main.go\n./xpath_generator\n```\n\n## � Troubleshooting \u0026 Best Practices\n\n### ❌ Common Issues \u0026 Solutions\n\n| Issue | Problem | Solution |\n|-------|---------|----------|\n| **Element not found** | Pattern too specific | Use broader pattern (preceding vs preceding-sibling) |\n| **Multiple matches** | Pattern too generic | Add more specific conditions |\n| **Timing issues** | Element not loaded yet | Use explicit waits with following patterns |\n| **Performance slow** | Using preceding/following extensively | Prefer sibling patterns when possible |\n\n### ✅ Best Practices\n\n#### 🎯 Pattern Selection Strategy\n1. **Start Narrow**: Use sibling patterns first (faster, more reliable)\n2. **Expand Scope**: Use preceding/following if sibling doesn't work\n3. **Add Conditions**: Use attributes to make patterns more specific\n4. **Test Stability**: Verify patterns work across different data sets\n\n#### 🚀 Performance Optimization\n```groovy\n// ❌ Slow - searches entire document\ndef element = findElement(\"//XCUIElementTypeButton/following::*[contains(@name,'Submit')]\")\n\n// ✅ Fast - limited scope\ndef element = findElement(\"${formContainer.xpath}//XCUIElementTypeButton/following-sibling::*[contains(@name,'Submit')]\")\n```\n\n#### 🔍 Debugging Tips\n1. **Use Browser Dev Tools**: Test XPath patterns in browser console\n2. **Start Simple**: Begin with basic patterns, add complexity gradually\n3. **Check Parent Context**: Ensure you're in the right container\n4. **Validate Data**: Test with different data sets and UI states\n\n## �📚 Referensi\n\n- [XPath Specification](https://www.w3.org/TR/xpath/)\n- [XCUITest Documentation](https://developer.apple.com/documentation/xctest)\n- [UI Automator Documentation](https://developer.android.com/training/testing/ui-automator)\n\n## 🤝 Contributing\n\nContributions welcome! Please read the contributing guidelines and submit pull requests untuk improvements.\n\n## 📄 License\n\nThis project is licensed under the MIT License - see the LICENSE file for details.\n\n## 📹 Demo Video\n\nUntuk melihat aplikasi dalam action, check out `demo.gif` yang menampilkan:\n- ✅ XML input dan parsing\n- ✅ Element selection dan analysis\n- ✅ Pattern generation dengan confidence ratings\n- ✅ Copy-to-clipboard functionality\n- ✅ Responsive design di berbagai ukuran layar\n\n\u003e **Note**: `demo.gif` file harus dibuat dengan screen recording dari aplikasi yang sedang berjalan untuk memberikan gambaran visual yang lengkap kepada users.\n\n---\n\n**Dibuat dengan ❤️ untuk iOS \u0026 Android Test Automation**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frezapace%2Fparent-axes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frezapace%2Fparent-axes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frezapace%2Fparent-axes/lists"}