Friday, December 27, 2019

Web testing with Selenium/ Geb / WebDriver

Spock

@Stepwise forces tests to run sequentially in declared order (even if parallel spec runner). If a method fails, remaining tests will be skipped


To check if tests shoudl be run or skipped you can use annotations @Requires or @IgnoreIf
However theese only work with System variables, (not instance variables)

For instance variable assesment you can use junit Assume.assumeTrue function. See https://stackoverflow.com/questions/33818907/programmatically-skip-a-test-in-spock
It throws an exception that spock is already catching and thus ends up ignoring the test case
 

Geb / Selenium

just some notes on WebTesting

WebDriver comes with 4 finders https://www.w3.org/TR/webdriver1/#element-retrieval

The Find ElementFind ElementsFind Element From Element, and Find Elements From Element commands allow lookup of individual elements and collections of elements.

The parameter passed to the find method specifies the Locator strategy

heres some examples using the webdriver directly

// By class
List elementsList = driver.findElements(By.className("myClass"))
// by xpath
WebElement element = driver.findElement(By.xpath("myClass")) // xpath expressions are easily copyable from Chrome deveolper tab
//By CSS (using GEb waitFor here )
waitFor (10) { driver.findElement(By.cssSelector("table.table")).displayed }



Note with cssSelctor you can use :nth-child to subselect a specific element (This is similar to :eq operator in jquery however the count is 0 based in jquery but 1 based in nth-child). Note also that this might not be obvious. I was trying to select what appeared to be the third table but if you use the copy selector option from chrome it was (apparently) the 7th child
e.g
$("body > table:nth-child(3)")
in jquery can also use $("body > table:eq(3)") // Note zero based index

For information on Geb goto The Book of Geb. It has some nice groovy syntax to remove some boiler plate logic.

Testing in Chrome

You can test your selectors in Chrome
  • Press F12 to open up Chrome DevTools.
  • Switch to Console panel.
  • Type in XPath like $x(“.//*[@id=’id’]”) to evaluate and validate.
  • Type in CSS selectors like $$(“#id”) to evaluate and validate.
  • Check results returned from console execution.

Page Object Pattern

As well as writing tests directly you can abstract pages away with the page Object Pattern.


import geb.Page

class WwwSchoolsAjaxExamplePage extends Page{

  private  static final DEFAULT_DIV_CONTENT = 'Let AJAX change this text'

  static url = "ajax/ajax_example.asp"

  static at = {
      title=="AJAX Example"
  }

  static content = {
      theButton { $(".example button") }
      theResultDiv { $("#myDiv") }
  }

  def makeRequest() {
      theButton.click()
      waitFor { theResultDiv.text()!=DEFAULT_DIV_CONTENT }
  }

}