Tuesday, 7 August 2018

SE - 33 - Can we use multiple conditions when we apply Explicit wait

We can apply multiple conditions while implementing explicit wait in webdriver. We can give multiple conditions by using OR\AND with ExpectedConditions class. Example below :


public class MultipleWaits {

 public void mulwwait() {
  WebDriver driver = new ChromeDriver();
  
  WebDriverWait Wait = new WebDriverWait(driver , 10);
  Wait.until(ExpectedConditions.and(          //here AND\OR conditions can be applied here
    ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("Path1")),
    ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("Path1")),
    ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("Path1"))
    )
    );
 }
}
In the above example I have used AND conditions for giving multiple conditions to webdriver explicit wait. We can also use OR in place of it.

SE - 32 - Can we have Constructors inside constructor(or constructor chaining)

Yes we can have multiple constructors a class with different signatures. Also we can call the constructor from the constructor using this keyword :

See the example below :

public class ConstInConst {
// constructor 1
 ConstInConst(){
  this(1,2); //calling constructor 2
 }
//constructor 2
 ConstInConst(int i, int j) {
 this(4,5,6); // calling constructor 3
 System.out.println(i +" and "+ j);
 }
//constructor 3
 ConstInConst(int i, int j, int k) {
 System.out.println(i +" and "+ j + " and " + k);
 }

 public static void main(String[] args) {
  new ConstInConst();
 }
}
Output : 
4 and 5 and 6
1 and 2


In the above example we have created 3 constructors and called the second constructor in first and third in second. This term is also called constructor chaining. We can't call 2 constructors in a single constructor(only one is allowed at a time) . It gives error because the first line should call the constructor. 



Sunday, 5 August 2018

SE - 31 - Difference between .equals() and "==" operator


=> .equals
i) Its a method
ii) It can only be used for object comparison
iii) It does not looks for memory reference rather it looks for the objects(contents)

=> "=="
i) Its an operator (equality operator)
ii) It can be used for primitive as well as object comparison
iii) "==" compare two objects based on their memory reference(or address). It will return true only if two object has same reference or the reference it is comparing represent exactly same object . In the situation where the object reference are different then it will return false.

Example :

public class equalDotEquals {

 @Test
 public void equals() {
  
  Integer I1 = new Integer(10);
  Integer I2 = new Integer(10);
  System.out.println((I1==I2));
  System.out.println((I1.equals(I2)));
  //Now we are making the same reference
  I1=I2;
  System.out.println("-----------------------");
  System.out.println((I1==I2));
  System.out.println((I1.equals(I2)));
 }
}
Output of above program :

false
true
-----------------------
true
true


Here we can see that we created two objects I1 and I2  of Integer. We applied "==" and ".equals()" operator on it. The output of "== " is false but output of ".equals()" is true . The reason is that "==" is using reference for comparison but reference of both the objects are different so its showing false. But equal() method compares the content(object) so its showing true.
Now we made the references of both the variable same by using I1=I2. now both the operators are giving same output.

Wednesday, 1 August 2018

SE - 30 - Setting timer for a page to load completely by JavaScriptExecutor


Apart from waits there is one more synchronisation point through which we can check that the page is loaded or not or we can set a timeout for it. This can be achieved through java script executor.

Below code demonstrates that how we can use Javascriptexecutor to set a timeout and check that the page is loaded :
public void waitForLoad(WebDriver driver) {
    ExpectedCondition<Boolean> pageLoadCondition = new ExpectedCondition<Boolean>() {
                public Boolean apply(WebDriver driver) {
                    return ((JavascriptExecutor)driver)
                      .executeScript("return document.readyState").equals("complete");
                }
            };
    WebDriverWait wait = new WebDriverWait(driver, 30);
    wait.until(pageLoadCondition);

So here we can see that we are checking the document.readystate should be equal to true. We have kept this inside the expected condition and we are using this with webdriver explicitwait.

Tuesday, 31 July 2018

SE - 29 - WebDriver Timeouts

We have already heard about thread.sleep and other explicit waits but there are few waits which are provided by WebDrivers too :

1) implicitlyWait : Specifies the amount of time the driver should wait when searching for an element if it is not immediately present. It works on DOM level. When searching for a single element, the driver should poll the page until the element has been found, or this timeout expires before throwing a NoSuchElementException. When searching for multiple elements, the driver should poll the page until at least one element has been found or this timeout has expired.
Increasing the implicit wait timeout should be used judiciously as it will have an adverse effect on test run time, especially when used with slower location strategies like XPath.

2) setScriptTimeout : Sets the amount of time to wait for a page load to complete before throwing an error. Sets the amount of time to wait for an asynchronous script to finish execution before throwing an error. If the timeout is negative, then the script will be allowed to run indefinitely.

3) pageLoadTimeout : Sets the amount of time to wait for an asynchronous script to finish execution before throwing an error. Sets the amount of time to wait for a page load to complete before throwing an error. If the timeout is negative, page loads can be indefinite.


WebDriver driver = new ChromeDriver();
driver.manage().timeouts().pageLoadTimeout(40, TimeUnit.SECONDS);
driver.manage().timeouts().setScriptTimeout(40, TimeUnit.SECONDS);
driver.manage().timeouts().implicitlyWait(40, TimeUnit.SECONDS);



Sunday, 29 July 2018

SE - 28 - TestNG Parameterization through @Parameters Annotation

There are few important points to keep in mind for Parameterization through @Parameter annotation in TestNG:

Consider the following example :
Program :
package Package1;

import org.testng.annotations.Optional;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

public class Pack1class1 {

 @Test
 @Parameters({"Parameter1","Parameter2"})
 public void P1c1M1(String Parameter1 ,String Parameter2) {
  System.out.println("Package1_class1_Method1");
  System.out.println(Parameter1);
  System.out.println(Parameter2);
 }
 
}
testng.xml :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
 <parameter name="Parameter1" value="TestParm1"></parameter>
  <parameter name="Parameter2" value="TestParm2"></parameter>

  <test thread-count="5" name="Test">
      <classes>
      <class name="Package1.Pack1class1"/>
     </classes>
  </test> <!-- Test -->
</suite> <!-- Suite -->
-> We can give only one parameter value for one type of parameter. If we want to have multiple values then we can use data-providers. In the above example we have defined 2 parameters Parameter1 and Parameter2 with single value. The purpose of these parameters are just to give the value from testng.xml.


-> If we try to give more values by giving comma then script will consider it as one single string:
 <parameter name="Parameter1" value="TestParm1"></parameter>
  <parameter name="Parameter2" value="TestParm2 , TestParam3"></parameter>
In this example we have tried to give two values in parameters , but TestNg will consider it as a single parameter and output will be TestParm2 , TestParam3
There is no way to give 2 parameter values.


-> Now in another try if we  give different values by creating new line in testng.xml fil as below :
 <parameter name="Parameter1" value="TestParm1"></parameter>
  <parameter name="Parameter2" value="TestParm1"></parameter>
  <parameter name="Parameter2" value="TestParm3"></parameter>
Here we can see that we are trying to give 2 different values to Parameter2 but while execution only the last value will be considered and output will be TestParm3


-> Through testng.xml file the parameters can only be given at Suite and test level.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
 <parameter name="Parameter1" value="TestParm1"></parameter>
  <parameter name="Parameter2" value="TestParm1"></parameter>
  
  <test thread-count="5" name="Test">
    <parameter name="Parameter3" value="TestParm1"></parameter>
      <classes>
      <class name="Package1.Pack1class1"/>
     </classes>
  </test> <!-- Test -->
</suite> <!-- Suite -->


->In case if the parameter name is same in suite level and test level then test level parameter will get preference over suite level. So, in that case, all the classes inside that test level will share the overridden parameter, and other classes which are outside the test level will share suite level parameter.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
 <parameter name="Parameter1" value="TestParm1"></parameter>
  <parameter name="Parameter2" value="TestParm1"></parameter>
  
  <test thread-count="5" name="Test">
    <parameter name="Parameter2" value="TestParm2"></parameter>
      <classes>
      <class name="Package1.Pack1class1"/>
     </classes>
  </test> <!-- Test -->
</suite> <!-- Suite -->
So here the TesgNG will pick the value of the Parameter2 from the Test level that is TestParm2. The value at suite level will be ignored. The output of the above program will be :

Package1_class1_Method1
TestParm1
TestParm2


-> If the parameter has no value in testng.xml then we can give @Optional annotation and define he default value.
(i) Program with @Optional value but we have Parameters present in Testng.xml
package Package1;
import org.testng.annotations.Optional;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

public class Pack1class1 {
 @Test
 @Parameters({"Parameter1","Parameter2"})
 public void P1c1M1(@Optional ("ABC") String Parameter1 ,@Optional("XYZ")String Parameter2) {
  System.out.println("Package1_class1_Method1");
  System.out.println(Parameter1);
  System.out.println(Parameter2);
 }
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
 <parameter name="Parameter1" value="TestParm1"></parameter>
  <parameter name="Parameter2" value="TestParm1"></parameter>
    <test thread-count="5" name="Test">
      <classes>
      <class name="Package1.Pack1class1"/>
     </classes>
  </test> <!-- Test -->
</suite> <!-- Suite -->
Since we have valid values in testng.xml for the given parameters so output of above program will be :
Package1_class1_Method1
TestParm1
TestParm1

(ii) Program with @Optional value but we don't have Parameters present in Testng.xml
package Package1;
import org.testng.annotations.Optional;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

public class Pack1class1 {
 @Test
 @Parameters({"Parameter1","Parameter2"})
 public void P1c1M1(@Optional ("ABC") String Parameter1 ,@Optional("XYZ")String Parameter2) {
  System.out.println("Package1_class1_Method1");
  System.out.println(Parameter1);
  System.out.println(Parameter2);
 }
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
 <parameter name="Parameter1" value="TestParm1"></parameter>
    <test thread-count="5" name="Test">
      <classes>
      <class name="Package1.Pack1class1"/>
     </classes>
  </test> <!-- Test -->
</suite> <!-- Suite -->
Here we can see that there is just one parameter in testng.xml but we are passing 2 parameters in our program. In this case the optional value will be called for second parameter, Output will be :

Package1_class1_Method1
TestParm1
XYZ

-> Now there can be a situation when the parameter type in xml is string and in method we have given int.  It means there is type mismatch in the parameter type. In this case we get the following exception:

[Utils] [ERROR] [Error] java.lang.NumberFormatException: For input string: &quot;ABC&quot;

Monday, 23 July 2018

SE - 27 - Comparator and Comparable


Comparable :
i) Interface that needs to be implemented:  java.lang.Comparable
ii) A comparable object compares its own instance with other class object instance
iii) It has only one method , Syntax : int obj1.compareTo(obj2)
iv) Returns : Negative , if obj1< obj2
                     Zero ,  if obj1 = obj2
                     Positive ,  if obj1 > obj2
v) Default natural sorting order
vi) All wrapper and string classes implements comparable


Comparator:
i) Interface that needs to be implemented:  java.util.Comparator
ii) An object of comparator compares objects of two different class instances
iii) It contains 2 methods :
      Syntax : int compare(obj1, obj2) , Int equals(obj1 , obj2)
iv) Returns : Negative , if obj1< obj2
                     Zero ,  if obj1 = obj2
                     Positive ,  if obj1 > obj2
v) Customised sorting order
vi) Collator and ruleBased collator implements comparator.