# स्वचालित UI परीक्षण

> ग्राफ़िकल रनटाइम में चलने वाले TestCase/TestSuite, स्क्रीनशॉट की दृश्य तुलना (golden images) के साथ।

Source: https://crossfly.dev/hi/docs/best-practices/testes — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# स्वचालित UI परीक्षण

CrossFly का परीक्षण फ्रेमवर्क **JUnit नहीं है**। प्रत्येक `TestCase` **ग्राफ़िकल रनटाइम के अंदर** चलता है
(paint thread, `EventsProcessor`, GL पाइपलाइन), और मुख्य assertion स्क्रीनशॉट की **दृश्य तुलना** है
संदर्भ-छवियों (*golden images*) के विरुद्ध। अध्याय 31 का पोर्टल।

## एक `TestCase` की शारीरिक रचना
```java
public class LoginTest extends TestCase {
   @Override protected void load() throws Exception {
      new LoginScreen().show();        // परीक्षण के अंतर्गत स्क्रीन बनाता है
   }
   @Override public void runTests() throws Exception {
      waitWindow(LoginScreen.class);
      type(0, TextField.class, "usuario@app.com");   // पहले TextField में टाइप करता है
      type(1, TextField.class, "senha123");
      click("Entrar");                 // उस टेक्स्ट वाले बटन पर क्लिक करता है
      shot();                          // golden को कैप्चर कर उससे तुलना करता है
      waitWindow(HomeScreen.class);
      shot();
   }
   @Override protected void unload() { /* स्थिति साफ़ करता है */ }
}
```
इंटरैक्शन: `click(...)`, `type(...)`, `enter()`, `penDown/penUp/penDrag(...)`, `setText(...)`।
खोज: `find(index, Classe)` / `find(texto, Classe)`। सिंक्रोनाइज़ेशन: `waitWindow(...)`,
`waitAnimation()`, `waitUIidle(...)`।

## समूहित करना और चलाना — `TestSuite`
```java
TestSuite suite = new TestSuite();
suite.startTests(new TestCase[]{ new LoginTest(), new CadastroTest() });
```
suite प्रत्येक परीक्षण चलाती है, `shot()` की goldens से तुलना करती है और रिपोर्ट करती है (`success`/`fail`/`log`)।

## ⚠️ डिटर्मिनिज़्म एक पूर्वापेक्षा है: `DeviceConfig.isTesting`
पिक्सेल-दर-पिक्सेल तुलना तभी मेल खाती है जब रेंडरिंग **डिटर्मिनिस्टिक** हो। `DeviceConfig.isTesting = true`
चालू करें — यह कर्सर को स्थिर करता है, timestamps हटाता है और `TimePicker`/घड़ी को
स्थिर बनाता है। **इसके बिना, golden कभी मेल नहीं खाता** (पलकता कर्सर, वर्तमान समय, आदि छवि बदल देते हैं)।

## बिना UI के: `WindowlessTestCase`
उस तर्क के लिए जिसे स्क्रीन की आवश्यकता नहीं है (repository, फ़ॉर्मेटिंग), `WindowlessTestCase` का विस्तार करें — यह
रनटाइम में चलता है, लेकिन UI बनाए बिना।

## डॉक्युमेंटेशन की छवियाँ उत्पन्न करना
वही परीक्षण स्क्रीनशॉट **डॉक्युमेंटेशन/स्टोर की छवियाँ उत्पन्न करने** के लिए भी काम आते हैं:
`Main.getScreenShot(true).toPng("prefixo_")`।

## अच्छी प्रथाएँ
- परीक्षण बैटरी में **हमेशा** `DeviceConfig.isTesting = true`।
- `shot()` से पहले `waitWindow(...)`/`waitAnimation()` का उपयोग करें — एक **स्थिर** फ़्रेम कैप्चर करें।
- प्रत्येक प्रासंगिक दृश्य स्थिति के लिए एक golden; जानबूझकर UI बदलने पर पुनर्जनन करें।

## आम गलतियाँ
- ऐसा golden जो "कभी हाँ, कभी नहीं गायब होता है" → `isTesting`/`waitAnimation` की कमी (अस्थिर फ़्रेम)।
- विंडो के पूरी तरह दृश्यमान होने से पहले `shot()`।
