【问题标题】:How to call method from any other page without declaring method as static using GEB and Spock?如何在不使用 GEB 和 Spock 将方法声明为静态的情况下从任何其他页面调用方法?
【发布时间】:2016-04-20 05:05:15
【问题描述】:

我想在 2-3 页中使用以下函数,所以我想调用该函数但出现异常“需要静态方法...”

这里的代码CommonFunction是一个扩展Page Class的类

def  "User clicks on My Account Link"(){

    CommonFunction."User clicks on My Account Link"()   
}

我也尝试了以下方法,但仍然出现异常“geb.error.PageInstanceNotInitializedException:页面类 com.casestudy.util.CommonFunctions 的实例尚未初始化。请将其传递给 Browser.to()、Browser.via() , Browser.page() 或 Browser.at() 使用前。”

CommonFunctions commonfunction= new CommonFunctions()
def  "User clicks on My Account Link"(){

     commonfunction."User clicks on My Account Link"()  
}

这里是函数用户点击我的帐户链接()的代码

def  "User clicks on My Account Link"(){
    def actions = new Actions(driver)
    myaccountMenu.displayed
    WebElement myaccountMenu = myaccountMenu.firstElement()
    actions.click(myaccountMenu).build().perform()

}

【问题讨论】:

  • 您需要先转到某个页面,然后才能与页面进行交互
  • 是的,我编写了这样的代码:class HomePage extends CommonFunctions{ CommonFunction."User clicks on My Account Link"()} 和 CommonFunction 类我扩展了 Page Class 并导入了这个类 geb.page

标签: groovy spock geb


【解决方案1】:

有点不清楚您到底要做什么,但看起来您在多个页面上都有一个“我的帐户”链接,并且您希望有一种方法可以单击该链接,而无需在每个页面上重复代码。如果是这种情况,您应该这样做:

创建一个“BasePage”类,所有其他具有“我的帐户”功能的页面都应该扩展它。

class BasePage extends Page{

  static content = {
    myAccountLink { $("#myAccountLink") } //CSS selector for the link you want on your page
  }

  //You don't actually need this method. In your tests you can just say myAccountLink.click() and it'll still work.
  def "User clicks on My Account Link"(){
    myAccountLink.click()
  }
}

那么你的其他页面可以定义为:

class HomePage extends BasePage {
  ... 
}

并且在您的测试中,只要浏览器位于从 BasePage 扩展的页面上,您就可以调用该方法:

def "User can go to my account page"(){
 setup:
    to HomePage

 when: "The user clicks the MyAccount link"
   "User clicks on My Account Link"()

 then:
   at MyAccountPage
}

【讨论】:

  • 谢谢,实际上我想在所有页面中使用这行代码: def "用户点击我的帐户链接"(){ def actions = new Actions(driver) myaccountMenu.displayed WebElement myaccountMenu = myaccountMenu.firstElement() actions.click(myaccountMenu).build().perform() }
  • 嗨,请看我编辑的问题,希望你能理解,在 Selenium 和 Java 中,我们曾经在单独的页面或类中编写通用函数,每当需要这些函数时,我们都会通过它的对象调用.function 名称,所以通过这种方式,我们的代码是多余的。
  • Geb/Groovy 没有必要这样做。你试过我的解决方案了吗?
  • 我正在使用的网站需要鼠标悬停,因此需要操作方法,并且您的建议对我不起作用,因为我已经在我的代码中尝试过,然后再将此问题发布到堆栈溢出。跨度>
  • 不能把那个方法放到BasePage类里吗?那么所有扩展它的页面都可以使用它
【解决方案2】:

我在子类中更改了函数名,然后在子函数中调用了函数(这里父函数名现在与子函数名不同)

谢谢Jk,你的建议也很好用

【讨论】:

    【解决方案3】:

    如果您有一个可以存在于多个页面上的通用组件,那么您要做的是创建一个带有其控制访问器的 Geb“模块”,然后将该模块包含在包含该模块的页面中。

    class moduleName extends Module {
        static clickUserLink() { userLink.click() }
        static content = {
            userLink = {$(locator)}
        }
    }
    
    class pageName extends Page {
        static content = {
            localName { module moduleName }
        }
    }
    

    这样,您的 clickUserLink 将迁移到您通过 localName.clickUserLink 导入模块的任何页面。您还可以考虑在 clickUserLink 方法或 helper 方法中添加 waitFor(userLink)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-18
      • 1970-01-01
      • 2019-08-07
      • 1970-01-01
      • 2017-10-08
      相关资源
      最近更新 更多