//Java Installation

// Eclipse Installation
> 'New Java Project' 
- src > 'New Java Class'
 - Download Selenium Jar file for Java.
 // Adding 'External Jar' ( Downloaded Selenium exe files ) to the Project Properties. ( As Class not Module )  ( ProjectName => Properties => Libraries ), Which will be used to import methods used in project.
 * Need to do for every project.
 // 'https://www.selenium.dev/selenium/docs/api/java/overview-summary.html'   ( Java API for Selenium )
//For Each browser we need different 'Invoke' file.
 System.setProperty(key, value );
  key = 'webdriver.chrome.driver' ( It's provided by the respective browser developers, Will be different for each browser  )             value = 'Address of invoked file on PC'    
// Create new object.
 className driver = new className();
/* driver: is object
 new : creates new memory for the class */


//                       Basic set up;
  		//Invoking .exe file from Google Chrome 
		System.setProperty("webdriver.chrome.driver", "C:\\Users\\jpann\\Downloads\\Don't Delete\\chromedriver.exe");
		//Creating Object.
		WebDriver driver1 = new ChromeDriver();

// Invoking for FireFox.
    System.setProperty("webdriver.gecko.driver","Location of           firefox invoke file.")
      //Creating Object.
		WebDriver driver1 = new FirefoxDriver();

          /*   WebDriver Methods.  
//Creating Object.
WebDriver driver1 = new ChromeDriver();          

//Pass the URL to open. 

//Return URL
//Return the Page Source.

//This can be used to navigate the browser ( Go to next or previous link )

//Once the execution is over, Close the test. (current window)

//Once the execution is over, This will close all the Child Windows.

   /* Locator Techniques & Tools used to identify Objects.  
 //Locators: ( the 'selector' is called 'Web Element in Selenium' )
 driver1.findElement(By.id("id_NameHere")); //Will locate using 'id'.
 driver1.findElement(By.className("class_NameHere")); // Will locate using 'class name',

// Will locate the element using Tag Name.

 driver1.findElement(By.linkText("forget password?"));
//It will locate the element by the exact text present in the tag.

//Sending Data to an element ( To Input Field ),
 driver1.findElement(By.id("id_NameHere")).sendKeys("Text is added from Selenium.")

//It will get the text from #text

- ID's with Numerical values might be dynamic. It might change with clicks/time. So avoid selecting such tags using ID
- Classes with spaces won't work. ( Compound classes will not work )
- If there are two same ID's Selected. It will select the first one.

 //This will click the button with class 'buttonPlay'

 // xpath

> Inspect (F12) on any selected element > Right click on HTML  code on right side ( on the element) > copy > XPath.
> This xpath can be used to select the element.
> This is not always 100% accurate.
> Double quotes inside the double quote won't work. ( use single quotes inside.)
> If the xpath starts with "html/body...", Then it is not relialble to use the path. 
> Might be different path for browsers.  
> Can be created in number of ways. ( using tag/class/attribute/id...)

> Before running the Scipts, We can validate the 'xpath' first, It will save time.
  - We can check/validate the xpath manually by running 
    > $x("xPathHere...") ( It should be written in browser's console, if it returns a array/object then it means the path is valid, if it show null then it's incorrect path)
  - Other way to check the path is to use a extension on the browser.                       
                   > Customized xpath 
 syntax:   //tagName[@attribute='value']
  /*for example */
 - //div[@id='box1'] ( double forward slash are part       of the code, Not comments)
 - //*[@id='username']  
   /*  Here it will  select any tags with id 'username' ( '//' is part of the code, not comments ) */
           > Creating xpath using Regular expression:
 - Sometimes in attributes the value string is fixed but the numerical values keep on changing, or if the value is too long but we know the format So in that case we can use syntax:


Example: <input id="username123"> </input>
> //input[contains(@id,'username')]
 // CSS selector
- CSSselector is 10 times faster than xpath.
> Inspect on any selected element > Right click on HTML  code on right side ( on the element) > copy > CSS selector.
> We can check/validate the path manually using ( in the browser console)
     $("Path here...")

- Css Customized selector:
tagName[attribute='value']   ( @ and '//' are not used here like xpath )

- CSS regular expression selector:

Example: <input id="name1233"> </input>

- Searching using Text
- Syntax : [class='class1 class2']


  // Traversing Through Elements

 // -parent-child
>  If there is no way to select the given element, We can select this tag using it's parent tag.
- define the xpath for parent and then direct to child using tagNames. 
Example: You want to select a 'input' tag and there is no unique/stable way to do it.
- Select it's parent tag first and then come to the child using tagNames, If on the way we have 2 same sibling tags then mention the number with it ( div[1] or divp[2] ).

  - parent : "//div[@class='1st-c']"

> Reach to Child using the parent now
- //div[@class='1st-c']/div/div[2]/div/input
-  parentTag/childTag/innerChildtag  

Child > Parent: ( only possible in xpath)

Example :
child: "//li[@id='item-1']"
- "//li[@id='item-1']/parent::ul"

  //Relative and Absolute xpath.
- Relative : Does not depend upon the Parent or the child node. Even if the parent/child tag is removed, Still the locator (Selected element) should work just fine.  
 Example : "//div[@id='username']"

- Absolute : Here the selector is depended upon the parent/child tags. if any change in the order ,then selector will be affected.
Example:  //section/div/div/div/div/ul/li[2]

      //Sibling Traversing ( "following-sibling::" )

- How to select/traverse through the siblings.

> "//li[@id='li-1']" ( This is the selected 'li' and we want to select it's 3rd sibling.) 
> "//li[@id='li-1']/following-sibling::li[3]"

    //Locating using 'text'  ( using xpath )  
Syntax: "//*[text()=' specificWord ']"
// '*' It represents any tag can be selected.                      
> driver1.findElement(By.xpath("//*[text()=' Singh ']")).getText();                      
//The word should be exactly on the HTML, Include spaces both sides if there are spaces on the HTML code.                      
   /* Selenium Web Drivers
//SELECT :                      
// >Static Dropdown: How to select  option from dropdown list.      
> Select sElement = new Select(elementLocation);
// 'Select' is the in-built class to manage 'select' element.
- We can choose 'option' in 3 ways.
 > sElement.selectByValue("JPY");
 > sElement.selectByIndex(3);
 > sElement.selectByVisibleTest("CANADIAN DOLLAR");

> sElement.deselectAll(); //Will de-Select all the options.

> Thread.sleep(time);
- We can use this to wait for the webpage/Program to laod, So as the next line codes can be executed after 2 seconds.

//Dynamic Dropdown.
- If there are two elements with exactly the same path, It will only select the first one.
- To select the second one, use ("(//a[@value='DEL'])[2]"));
- This will select using it's index.    

: It's not alway good idea to use index, So we use 'Parent-Child' locator,
- So Select the Parent Tag first and then it's child ( This way even if there are two elements with same name, But there Parent could be different.)

Example" ( 1 space after the Parent Element and then the child element Xpath. ):
( //input[@id='ctl00_mainContent_ddl_destinationStation1_CTXT'] //*[@value='DEL'] )
//AutoSuggestive Dropdown.  
: When user type something, The input field will provide some autoSuggestive results ( google, youtube...)

: To Clear the Pre-populated data OR sometimes we just select on the input field and it clears the data.
> .selector().clear();
> .selector().click();

: Use 'Down arrow' button and select using 'Enter'
> .selector()).sendKeys(Keys.DOWN);
> .selector()).sendKeys(Keys.ENTER);

: We can use 'selector' into an variable and re-use it multiple times.
WebElement element = drivere.findElement(By.id("idName"));
element.sendKeys("New Text To Seach");
element.sendKeys(Keys.ENTER); //This will push 'Enter' button.

//Radio Buttons:
- We can select button using the usual 'WebElement' 
- we can use  '//input[@name='group1']' to check/compare/code/test the size of the Inputs with same group name.

- Here is the example to select inputs of same group using it's index.
> driver.findElement(By.xpath("//input[@name='group1'][1]")).click();
> Thread.sleep(1000);
> driver.findElement(By.xpath("//input[@name='group1'][3]")).click();
> Thread.sleep(1000);
> driver.findElement(By.xpath("//input[@name='group1'][2]")).click();

- It will return the Size of the input with same same group name.
> driver.findElements(By.xpath("//input[@name='group1']")).size()
> driver.findElements(By.xpath("//input[@type='radio']").get(0);
//It will select the first element.                     

//Play with Attributes:
> selector.getAttribute("value");
> selector.getAttribute("name");
> selector.getAttribute("id");
> selector.getAttribute("class");

//Check the size of the input radio button with same group name.
> int count = driver.findElements(By.xpath("//input[@name='group1']")).size();
> for (int i = 0 ; i < count ; i++ ) {
 //Print the 'attribute's Value of name = 'group1'. We are using loop and it's findElement(s).`
> String checkText = driver.findElements(By.xpath("//input[@name='group1']")).get(i).getAttribute("value");
> if(checkText.equals("Milk")) {
> System.out.println("Milk Found: "+ i);							 driver.findElements(By.xpath("//input[@name='group1']")).get(i).click();

                   /*--------  */

/*  Java Alerts  */
: How can we manage the pop ups which are not web based element's. ( Which are not coded through HTML/Css/Js) are coded through 'Java'.

//We need to switch from 'web' to 'popup' View,So we can manage popups.
> driver.switchTo().alert().getText(); //This will return the whole 'text'on the PopUp.
> driver.switch().alert().sendKeys("Karan Singh"); //This can be used to Pass the value in the text field on PopUp.
> driver.switchTo().alert().accept(); // 'accept' will indicate as:'OK'|'agree'|'accept'
> driver.switch().alert().dismiss(); // 'dismiss' will indicated as 'cancel' | 'No' | 'Ignore'.

                   /*--------  */

//Check Boxes.
> ("//input[@type='checkbox']")
 - It will return all the checkboxes on the given web page. ( use findElements )
> selector.isSelected(); //It will tell if checkbox is selected or not.
> selector.click();

                   /*--------  */

- It is a way to check if the Test case Passed or Failed. We are not to use console log's to check the results and see if the test is passed or failed, In work we are to be use "Assertions", Which will automatically tell if a test passes or failes. 
- Download 'testing Java' file and add it to your project Path.

- Boolean Check:
> Assert.assertTrue(data);
//This will expect a TRUE value to Pass the test.

> Assert.assertFalse(data);
//This will expect a FALSE value to Pass the test.

- Value Check: (String or value):
> Assert.assertEquals(selecter.getText(), "5 Adults");
: This will check the 'text' from selector and compare it to the '5 Adults'.

: We can select the current date using classes/ or some other way.
> selector.click();

//Check if the element is enabled or disabled.
> select.isSelected(); //This does not work some times, Because of the website/app. As it might appear it's disabled but the selenium gets confused.
- We can Test/check the specific classed/attributes in the element, Which will tell us if the element is disabled/removed.
> select.getAttribute("style")
//This will return a complete STRING of all the CSS properties.
> select.getAttribute("style").contains("opacity:1"); //True
> select.getAttribute("style").contains("opa"); //True
> select.getAttribute("style").contains("1"); //True
> select.getAttribute("style").contains("opp"); //False
> select.getAttribute("style").contains("1");
//We can check the string by using 'contains' method.

  /* ------------XX--XX--XX---------*/

       /*-------Deep Dive Into Function-------------- */

: Format Code & debugging
// This will format the code in the aligned format. 

: Naming Convection
- Class name should always start with capital letter ( Not camelCase )
- Variable should always be in lower case letters.
- Use CamelCase for Variable name.

- Debugging:
 > Right click on the line number and tap 'Toggle Breakpoint'
 > Debug As > Java Application.
 //This way the scipt will stop at toggled point and we need to manually push the 'next button' ( Step over or F6) to move to next line on script or push 'RESUME' it will resume the script in regular fashion.

//Adding Item Into the Carts