@@ -46,6 +46,50 @@ pwsh .github/scripts/BuildAndRunHostApp.ps1 -Platform [android|ios|maccatalyst]
4646
4747---
4848
49+ ## 🚨 CRITICAL: Unique Issue Tracker Requirement
50+
51+ ** ONE test page per issue number** - Multiple test pages with the same issue number will cause crashes!
52+
53+ ```
54+ ❌ CRASH ERROR:
55+ Please provide unique tracker + issue number combo: Github330080
56+ ```
57+
58+ ** Why this happens** : The test infrastructure requires unique ` [Issue(tracker, number)] ` combinations across ALL test pages.
59+
60+ ** Solutions** :
61+
62+ ** ✅ Option 1: Single comprehensive test page (PREFERRED)**
63+ ``` csharp
64+ // One test page testing multiple scenarios
65+ [Issue (IssueTracker .Github , 33008 , " Multiple test scenarios" , PlatformAffected .iOS )]
66+ public partial class Issue33008 : ContentPage
67+ {
68+ // All test UI in one page
69+ // Multiple SearchBars, buttons, etc.
70+ }
71+
72+ // One test file with multiple [Test] methods
73+ public class Issue33008 : _IssuesUITest
74+ {
75+ [Test ] public void Scenario1 () { }
76+ [Test ] public void Scenario2 () { }
77+ [Test ] public void Scenario3 () { }
78+ }
79+ ```
80+
81+ ** ❌ Option 2 WILL CRASH: Multiple test pages (DON'T DO THIS)**
82+ ``` csharp
83+ // ❌ WRONG: Multiple files with same issue number
84+ Issue33008SearchBar .xaml // [Issue(Github, 33008, ...)]
85+ Issue33008SearchHandler .xaml // [Issue(Github, 33008, ...)]
86+ // Result: CRASH - duplicate tracker combo
87+ ```
88+
89+ ** Rule** : If you need multiple test scenarios for one issue, put them ALL in ONE test page with multiple test methods.
90+
91+ ---
92+
4993## Two-Project Requirement
5094
5195** CRITICAL** : Every UI test requires code in TWO projects:
@@ -344,24 +388,69 @@ public void TestModifiesGlobalState()
344388 }
345389```
346390
347- ### 5. Use Appropriate Waits
391+ ### 5. Avoid Task.Delay Unless Necessary
392+
393+ ** ⚠️ GUIDELINE** : Prefer Appium's built-in synchronization, but use delays when tests require them.
394+
395+ ``` csharp
396+ // ✅ Preferred: Let Appium handle waiting
397+ App .Tap (" SetTextButton" );
398+ var status = App .FindElement (" StatusLabel" ).GetText ();
399+
400+ // ⚠️ Use When Necessary: Some tests need explicit delays
401+ App .Tap (" AnimateButton" );
402+ Task .Delay (500 ).Wait (); // Animation takes time
403+ var position = App .FindElement (" MovingElement" ).GetRect ();
404+ ```
405+
406+ ** When delays ARE needed** :
407+ - Animations must complete before measurement
408+ - Async operations without observable UI changes
409+ - Platform-specific timing requirements
410+ - Tests fail consistently without delay
411+
412+ ** When delays are NOT needed** :
413+ - Waiting for element to appear (use ` App.WaitForElement() ` )
414+ - Waiting for element to become interactive (use ` App.WaitForElement() ` )
415+ - Simple button taps and text updates (Appium waits automatically)
416+
417+ ** Rule of thumb** :
418+ 1 . Try without delay first
419+ 2 . If test fails consistently, add minimal delay
420+ 3 . Document WHY delay is needed
421+
348422``` csharp
349- // ✅ Good: Wait for specific element
423+ // ✅ Good: Documented necessary delay
424+ App .Tap (" StartAnimationButton" );
425+ Task .Delay (500 ).Wait (); // Wait for animation to complete
426+ var finalPosition = App .FindElement (" AnimatedElement" ).GetRect ();
427+
428+ // ❌ Bad: Unnecessary delay (FindElement waits automatically)
429+ App .Tap (" Button" );
430+ Task .Delay (500 ).Wait ();
431+ var text = App .FindElement (" Label" ).GetText ();
432+ ```
433+
434+ ### 6. Use Appropriate Waits (When Needed)
435+ ``` csharp
436+ // ✅ Good: Wait for specific element with custom timeout
350437App .WaitForElement (" ResultLabel" , timeout : TimeSpan .FromSeconds (10 ));
351438
352- // ❌ Bad: Fixed sleep (timing-dependent )
353- Thread . Sleep ( 5000 );
439+ // ✅ Good: Standard wait (uses default timeout )
440+ App . WaitForElement ( " ResultLabel " );
354441```
355442
356443## Checklist Before Committing
357444
358445- [ ] Two files created (XAML + NUnit test)
359446- [ ] File names match: ` IssueXXXXX `
447+ - [ ] ** UNIQUE** ` [Issue()] ` tracker+number combo (no duplicates across all test files)
360448- [ ] ` [Issue()] ` attribute present with all parameters
361449- [ ] Inherits from ` _IssuesUITest `
362450- [ ] ONE ` [Category] ` attribute from UITestCategories
363451- [ ] All interactive elements have ` AutomationId `
364452- [ ] Test uses ` App.WaitForElement() ` before interactions
453+ - [ ] Delays (` Task.Delay() ` ) only used when necessary and documented
365454- [ ] Test has meaningful assertions
366455- [ ] Test method name is descriptive
367456- [ ] No unnecessary platform directives
@@ -598,6 +687,37 @@ public partial class IssueXXXXX : ContentPage { }
598687public partial class IssueXXXXX : ContentPage { }
599688```
600689
690+ ### Using Task.Delay or Thread.Sleep
691+ ``` csharp
692+ // ⚠️ Avoid when possible (try without delay first)
693+ App .Tap (" Button" );
694+ Task .Delay (500 ).Wait ();
695+ var text = App .FindElement (" Label" ).GetText ();
696+
697+ // ✅ Good: Use when necessary with explanation
698+ App .Tap (" AnimateButton" );
699+ Task .Delay (500 ).Wait (); // Animation duration requires wait
700+ var position = App .FindElement (" Element" ).GetRect ();
701+
702+ // ✅ Better: Prefer Appium's synchronization when possible
703+ App .Tap (" Button" );
704+ var text = App .FindElement (" Label" ).GetText (); // Waits automatically
705+ ```
706+
707+ ** Guideline** : Try without delays first. Add only if tests fail consistently, and document why the delay is needed.
708+
709+ ### Duplicate Issue Tracker Numbers
710+ ```
711+ // ❌ Bad: Multiple test pages with same issue number
712+ Issue33008SearchBar.xaml [Issue(Github, 33008, ...)]
713+ Issue33008SearchHandler.xaml [Issue(Github, 33008, ...)]
714+ // RESULT: App crashes with "unique tracker + issue number combo" error
715+
716+ // ✅ Good: One test page with multiple test methods
717+ Issue33008.xaml [Issue(Github, 33008, ...)]
718+ Issue33008.cs { Test1(), Test2(), Test3() }
719+ ```
720+
601721## Troubleshooting
602722
603723** Test Won't Compile** :
0 commit comments