Automated testing - 8 positioning methods and waiting for detailed explanation

Posted by QSDragon on Thu, 30 Dec 2021 19:17:23 +0100

1.id – the value of id in the tag

If the developer programming specification, the element id of the page is not repeated and is not a dynamically generated id, it is very easy to use id positioning.

//<select style="width: 33%" id="CityCode" name="CityCode" class="form-control lopicker">
//Use id to locate element
WebElement element =  driver.findElement(By.id("CityCode"));

2.name – the value of name in the tag

//<select style="width: 33%" id="CityCode" name="CityCode" class="form-control lopicker">

//Use name to locate the element
WebElement cityelement = driver.findElement(By.name("CityCode"));

3.className - the value of the class attribute in the tag

 //<select style="width: 33%" id="ProvinceCode" name="ProvinceCode" class="form-control lopicker">
 //Locate using className

     WebElement element =  driver.findElement(By.className("form-control"));

4.tagName – tag name

//<select style="width: 33%" id="ProvinceCode" name="ProvinceCode" class="form-control lopicker">
//Locate elements using tag names

     WebElement element = driver.findElement(By.tagName("select"));

5.linkText – all text values in a tag

//< a href = "/ competition / detail / c05a5ae3-32c6-4b81-b042-646ad8de275a" title = "treasure hunt robot competition" class = "link item_title" > treasure hunt robot competition</a>
    WebElement comElement = driver.findElement(By.linkText("Treasure hunt robot competition"));

6.partialLinkText – a is the text value of the part in the tag

//< a href = "/ competition / detail / c05a5ae3-32c6-4b81-b042-646ad8de275a" title = "treasure hunt robot competition" class = "link item_title" > treasure hunt robot competition</a>
     WebElement comElement = driver.findElement(By.partialLinkText("Treasure hunt"));

7.CSSSelector – css selector (very important)

//<select style="width: 33%" id="ProvinceCode" name="ProvinceCode" class="form-control lopicker">
     WebElement element = driver.findElement(By.cssSelector(".form-control"));
        WebElement element1= driver.findElement(By.cssSelector("select.form-control"));
/**
       * (Tags with attributes) are very common CssSelector: tag name [attribute name = 'attribute value'] [attribute name = 'attribute value'] [attribute name = 'attribute value'] [attribute name = 'attribute value'] [attribute name = 'attribute value']
       */
     //<select style="width: 33%" id="CityCode" name="CityCode" class="form-control lopicker">
    WebElement cityelement = driver.findElement(By.cssSelector("select#CityCode"));
    WebElement cityelement1 = driver.findElement(By.cssSelector("#CityCode"));
    WebElement cityelement2 = driver.findElement(By.cssSelector("select[name='CityCode']"));
    WebElement cityelement3 = driver.findElement(By.cssSelector("select[class='form-control lopicker'][name='CityCode']"));

8.xpath – relative path / absolute path

The relative or absolute path of the element can be obtained by using the xpath plug-in of chrome or Firefox.

chrome:

fireFox:

//<select style="width: 33%" id="AreaCode" name="AreaCode" class="form-control lopicker">
     //Positioning through a single attribute
     WebElement areaElement = driver.findElement(By.xpath("//*[@id=\"AreaCode\"]"));
     //Locating through multiple attributes
     WebElement areaElement1 = driver.findElement(By.xpath("//select[@style='width: 33%' and @name='AreaCode']"));
//< a href = "/ competition / detail / c05a5ae3-32c6-4b81-b042-646ad8de275a" title = "treasure hunt robot competition" class = "link item_title" > treasure hunt robot competition</a>
     //Through the contains expression
     WebElement comElement1 = driver.findElement(By.xpath("//A [@ class ='link item_title 'and contains (text(),' Robot Competition ')] ");
     //Through the startsWith expression
     WebElement comElement2 = driver.findElement(By.xpath("//A [@ class ='link item_title 'and starts with (text(),' treasure hunt ')] ");
     //If the reader's Google version only supports XPath 1 0, so ends with cannot be used
    // WebElement comElement3 = driver. Findelement (by. XPath ("/ / a [@ class ='link item_title 'and ends with (text(),' robot game ')])));
     //If ends with is not supported, the following method can be used instead
     WebElement comElement4 = driver.findElement(By.xpath("//A [substring (text(), string length (text()) - string length ('human race ') + 1) =' human race '] ");

Eight methods of locating elements are summarized above.

Some special cases are described below:

1.id is generated dynamically.

In this case, other positioning methods can be selected. Such as cssselector, XPath, etc

For example, the generated id always ends with the register string:

<input id="m.f0.menu.f2.volumeTabs.BLOCK_COMMON.tcw.form.register" name="m.f0.menu.f2.volumeTabs.BLOCK_COMMON.tcw.form.register" class="aranea-checkbox" type="checkbox"> </td>

At this point, you can find it through xpath

driver.findElement(By.xpath("//input[ends-with(@id,'register')]"));

If the dynamic id has rules to follow, you can also locate elements by id. There are no specific examples.

2. Search elements can be encapsulated into corresponding methods and called directly. It is convenient to add log information.

/**
     * Method to find element element
     */
    public WebElement findElementBy(By by) {
        return driver.findElement(by);
    }

    /**
     * Method for finding multiple elements elements elements
     */
    public List<WebElement> findElementsBy(By by) {
        return driver.findElements(by);
    }

    /**
     * After finding multiple elements, continue to find them downward (locate an element, which is a pile of the same elements, select one of them, and then continue to locate in the selected elements)*/   public WebElement getOneElement(By bys, By by, int index) {     return findElementsBy(bys).get(index).findElement(by); }

3. When looking for an element, you will consider whether the element resource has been loaded.

Here is a summary of "waiting" in automated testing:

1. Hard wait - encapsulated into methods for easy calling.

/**
* Hard wait: sleepTime.
*/
public void Wait(int sleepTime) {
if (sleepTime <= 0) {
return;
}
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

2. Implicit wait - this wait is global and specific to the current driver. Once set, as long as the driver executes the findElement or findElements method, it first goes back to find the element. If it is not found, it will poll for the element within the set time until timeOut Because it is global, some elements do not need to wait, so it will cause a waste of time. Because the browser renders from top to bottom, if element 1 is above element 2, you don't need to wait when you first find element 2 and then find element 1. However, after the global parameter is set, it will still wait.

driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

3. Display waiting (recommended)

/**
     * Provides a method of intelligently waiting to find elements
     * @param driver
     * @param time
     * Timeout wait time for element
     * @param by
     * @return
     */
    public static WebElement waitElement(WebDriver driver,int time,By by) {
        WebElement element=null;
        
        WebDriverWait wait = new WebDriverWait(driver, time);
        
        try {
            element = wait.until(new ExpectedCondition<WebElement>() {

                public WebElement apply(WebDriver driver) {
                    WebElement element = driver.findElement(by);
                    return element;
                }
            });
        } catch (TimeoutException e) {
            System.out.println("element"+by.toString()+" "+time+"S Could not be found within");
            logger.info("Element not found");
        }
        
        
        return element;
        
    }
    
    /**
     * Provide an external method of intelligent waiting to find elements, with a fixed waiting timeout of 5S
     * @param by
     * @return
     */
    public static WebElement waitElement(By by) {
        
        WebDriver driver= GetDriverUtil.getDriver();
        return waitElement(driver, 5, by);
        /*WebElement element = null;
        try {
            element = (new WebDriverWait(driver, 5)).until(new ExpectedCondition<WebElement>() {

                @Override
                public WebElement apply(WebDriver driver) {
                    
                    return driver.findElement(by);
                }

            
            });
        } catch (Exception e) {
            System.out.println("Element "+ by. Tostring() +" + "cannot find");
            e.printStackTrace();
        }
        
        return element;*/
    }

The above ExpectedConditions are written by ourselves. In fact, various element waiting conditions have been encapsulated in the ExpectedConditions class of selenium. If you are interested, you can find out

You can take a look at the source code. The anonymous internal class new ExpectedCondition {} is also used internally. Here is an example:

Determine whether an element can be clicked:

1. This element exists in dom

2. The element is visible

3. This element is enabled

/**
   * An expectation for checking an element is visible and enabled such that you can click it.
   *
   * @param locator used to find the element
   * @return the WebElement once it is located and clickable (visible and enabled)
   */
  public static ExpectedCondition<WebElement> elementToBeClickable(final By locator) {//Anonymous Inner Class 
    return new ExpectedCondition<WebElement>() {
      @Override
      public WebElement apply(WebDriver driver) {//Determine whether the element is visible
        WebElement element = visibilityOfElementLocated(locator).apply(driver);
        try {//Returns the element if it is visible and valid
          if (element != null && element.isEnabled()) {
            return element;
          }
          return null;
        } catch (StaleElementReferenceException e) {
          return null;
        }
      }

      @Override
      public String toString() {
        return "element to be clickable: " + locator;
      }
    };
  }

The above summary is the element waiting, which is used for automatic testing, and the timeout test for waiting for page loading.

a. Wait for the page to load and set the timeout. After the timeout, no longer wait, and directly locate an element. (js script needs to be executed)

/**
     *Wait for the page to load, and set the timeout for page loading. If the loading is not completed within the specified time, stop loading and locate the specified element
     * @param driver
     * @param timeout
     * @param by
     */
    
    public static void pageLoad(WebDriver driver,int timeout,String url) {
        try {
            //Set page load timeout
            driver.manage().timeouts().pageLoadTimeout(timeout, TimeUnit.SECONDS);
            driver.get(url);
        } catch (Exception e) {
            ((JavascriptExecutor)driver).executeScript("window.stop()");
        }
        
        driver.findElement(By.id("user[login]")).sendKeys("feifeifei");
        
    }

b. Sometimes the loading of a page times out and needs to be refreshed once to output the loading status of the page. (js script needs to be executed)

/***
     * Launch the browser and open the page
     */
    public void launchBrowser(String webUrl, int timeOut) {
        //getDriver () is the method of encapsulating the driver described in the previous blog
        driver = GetDriverUtil.getDriver();
        try {
            //Maximize browser window (encapsulated into method)
            maxWindow();
            //Set the time to wait for the page to load (encapsulated into a method)
            waitForPageLoading(timeOut);
            //Open the specified page of the browser (encapsulated into a method)
            get(webUrl);
        } catch (TimeoutException e) {
            logger.warn("The page is not fully loaded. Refresh and try again");
            //Refresh page
            refresh();
            //Create js script executor
            JavascriptExecutor js = (JavascriptExecutor) driver;
            //Execute the script to describe the loading status of the document The status is divided into
            //loading document is still loading
            //The interactive / interactive document has finished loading and the document has been parsed, but sub resources such as images, style sheets and frames are still loading
            //Complete / complete T document and all sub resources have been loaded. Status indicates that the load event is about to be triggered.
            
            String status = (String) js.executeScript("return document.readyState");
            //Print the returned status through the log
            logger.info("Print status:" + status);
        }

    }
Asynchronous requests are often encountered during automated testing, as shown in the following figure:

When you need to locate asynchronous request elements, you need to wait for the asynchronous script execution to complete and return results. At this time, you need to set the timeout of asynchronous script.

/** setScriptTimeout. Timeout for asynchronous scripts. (encapsulated as a method for easy calling) webdriver can execute scripts asynchronously. This is to set the timeout for the returned results of asynchronously executing scripts */
    public void setScriptTimeout(int timeOut) {
        driver.manage().timeouts().setScriptTimeout(timeOut, TimeUnit.SECONDS);
    }

Topics: Java Operation & Maintenance