浏览器重启使用Geb& Spock在同一测试中

时间:2017-02-06 13:44:16

标签: selenium spock geb

我希望能够使用Geb和Spock Framework重新启动我的浏览器会话测试。我没有如何关闭浏览器并在测试compltion等后更新,但是当我在测试期间关闭并尝试重新使用浏览器对象时,我得到selenium抛出的会话错误。下面是我试图执行的基本大纲。 NB从不允许我导航到新的StoreHome,如果我尝试使用浏览器,我会收到错误。

@Category(High.class)
def "TC1: Verify Browser Restart"() {
    when: "On my StoreFront HP wait until title displayed"
    to StoreHomePage
    waitFor { homepagetitle.displayed }

    then: "Update your site picker"
    mySitePicker.click()
    waitFor { myNewHomePageTitle.displayed }

    when: "Close the browser and insure on restart new page is loaded"
    browser.close()
    browser.quit()

    def nb = new Browser()
    nb.to(NewStoreHomePage)

    then: "Validate on New HP"
    asset myNewHomePageTitle.displayed
}

2 个答案:

答案 0 :(得分:4)

就像在规范中执行以下操作一样简单:

resetBrowser()
CachingDriverFactory.clearCacheAndQuitDriver()

之后,任何尝试访问browser的代码都会触发自动创建新的WebDriverBrowser个实例。

答案 1 :(得分:0)

这是强制新驱动程序的方法:

CachingDriverFactory.clearCache()

我测试过它,效果很好。此提示也可以在Geb manual

中找到

更新2017-02-07 15:10 CET:感谢您提出后续问题。好吧,我的简短回答是在假设命令是在一个特征方法和一个特征方法下发出的,并且下一个特征方法以新的浏览器会话开始的。为了在测试中进行测试,您必须手动创建一个新的WebDriver实例,并以某种方式欺骗Geb更新其浏览器会话。

因为这至少是棘手的,我不知道该怎么做,我建议使用两个单独的功能方法来测试退出浏览器之前和之后应该测试的内容。如有必要,您可以通过@Shared成员在他们之间共享状态。这也有一个好处,如果你让Geb为你创建新的WebDriver和浏览器会话,将自动考虑GebConfig.groovy中配置的所有内容,例如浏览器类型和功能。如果你手动创建一个驱动程序,你必须自己解析Geb配置 - 丑陋!

但这种方法的主要问题是:如何确保特征方法以声明的(词法)顺序执行?通常,测试应该以任何顺序运行,因此您不能也不应该依赖于特定的执行顺序。 Spock提供Stepwise注释来解决您希望强制执行执行顺序的罕见情况,但是这会导致与中间测试情况相同的问题,因为Geb隐含地假设它应该继续在同一会议。即我们需要一个技巧来强制执行词法执行顺序而不使用@Stepwise

另一个问题是,如果您的规范扩展GebReportingSpec因为您想截取屏幕截图,那么在浏览器消失后,Geb无法在功能方法结束时拍摄最后一个屏幕截图。现在,如果测试通过reportOnTestFailureOnly成功,您可以配置Geb不截取屏幕截图,但这仍然使我们失败的测试。所以我添加了report方法的覆盖,并添加了一些额外的异常处理。

完整的解决方案看起来像这样,源自我的一个现实生活测试:

package de.scrum_master.tdd

import geb.driver.CachingDriverFactory
import geb.spock.GebReportingSpec
import org.openqa.selenium.Keys
import org.spockframework.runtime.model.FeatureInfo
import spock.lang.Shared

class SampleGebIT extends GebReportingSpec {

  @Override
  void report(String label = "") {
    // GebReportingSpec tries to write a report (screenshot) at the end of each feature
    // method. But because we use 'CachingDriverFactory.clearCacheAndQuitDriver()',
    // there is no valid driver instance anymore from which to get a screenshot. Geb is
    // unprepared for this kind of error, so we handle it gracefully so as to keep the
    // test from failing just because the last screenshot cannot be taken anymore.
    try {
      super.report(label)
    }
    catch (Exception e) {
      System.err.println("Cannot create screenshot: ${e.message}")
    }
  }

  // We cannot use 'specificationContext' directly from 'setupSpec()' because of this
  // compilation error: "Only @Shared and static fields may be accessed from here"
  // Okay then, so use we a @Shared field as a workaround. ;-)
  @Shared
  def currentSpec = specificationContext.currentSpec

  def setupSpec() {
    // Make sure that feature methods are run in declaration order. Normally we could
    // use @Stepwise for this, but because @Stepwise implies staying in the same
    // browser session, it would not work in connection with
    // 'CachingDriverFactory.clearCacheAndQuitDriver()'. This is the workaround for it.
    for (FeatureInfo feature : currentSpec.features)
      feature.executionOrder = feature.declarationOrder
  }

  def "Search web site Scrum-Master.de"() {
    setup:
    def deactivateAutoComplete =
      "document.getElementById('mod_search_searchword')" +
      ".setAttribute('autocomplete', 'off')"
    def regexNumberOfMatches = /Insgesamt wurden ([0-9]+) Ergebnisse gefunden/

    when:
    go "https://scrum-master.de"
    report "welcome page"

    then:
    $("h2").text().startsWith("Herzlich Willkommen bei Scrum-Master.de")

    when:
    js.exec(deactivateAutoComplete)
    $("form").searchword = "Product Owner" + Keys.ENTER

    then:
    waitFor { $("form#searchForm") }

    when:
    report "search results"
    def searchResultSummary = $("form#searchForm").$("table.searchintro").text()
    def numberOfMatches = (searchResultSummary =~ regexNumberOfMatches)[0][1] as int

    then:
    numberOfMatches > 0

    cleanup:
    println "Closing browser and WebDriver"
    CachingDriverFactory.clearCacheAndQuitDriver()
  }

  def "Visit Scrum-Master.de download page"() {
    when:
    go "https://scrum-master.de/Downloads"
    report "download page"

    then:
    $("h2").text().startsWith("Scrum on a Page")
  }
}

BTW,我在Windows 10机器上使用多个浏览器成功测试了这个:

  • HtmlUnit(使用已激活的JavaScript)
  • PhantomJS
  • Internet Explorer
  • 边缘
  • 火狐