Geb - 如何删除Geb中的属性

时间:2017-01-18 09:50:59

标签: geb

我想设置一个日期选择器的值,它具有属性' readonly'。我尝试removeAttr()删除了该属性,但是出现了这样的错误:

  

Caught:groovy.lang.MissingMethodException:没有方法签名:geb.navigator.NonEmptyNavigator.removeAttr()适用于参数类型:(java.lang.String)values:[readonly]

如何删除Geb中的属性?

Souce代码:

<input ng-show="!date" class="ui-form-control ng-isolate-scope" name="date" placeholder="StartTime" ui-datepicker-trigger="" selected-date="date" readonly="readonly" type="text">

我的geb代码:

$('input', placeholder: 'StartTime').removeAttr('readonly')

全部谢谢

3 个答案:

答案 0 :(得分:1)

WebDriver和Geb不允许您直接修改DOM。

您需要通过the js object使用javascript来执行此操作,如果您的网页因为Geb's jQuery integration而加载了jQuery,则会更加轻松。

答案 1 :(得分:0)

使用以下代码解决问题:

js.exec(
  "document.getElementsByClassName('ui-form-control ng-isolate-scope')[0]" + 
  ".removeAttribute('readonly')"
) 

答案 2 :(得分:0)

因为OP说它是一个AngularJS日期选择器,而且我从未与Angular有过任何接触,我自己也不是一个前端人员,我想学点东西,现在我和你分享它,无论它值多少钱。

这是一个不使用任何JS的Geb测试,但是纯粹通过Geb或Selenium从Angular日期选择器收集信息并与之交互。测试显示了如何

  1. 通过myNavigator.singleElement().getAttribute("value")从datepicker的文本字段中获取当前所选日期(也适用于非活动控件),
  2. 通过打开日期选择器并在日历中查找突出显示的日期来获取当前选择的日期(当然,仅适用于活动控件),
  3. 与日期选择器进行相当繁琐的互动,选择当前年份的圣诞节(12月25日)
    • 打开datepicker,
    • 点击当前月份以打开年月选择器,
    • 点击12月,再次有效关闭月份选择器,
    • 点击第25天,再次有效关闭日期选择器,
    • 最后通过阅读文本标签来检查是否设置了正确的日期,就像在示例#1中一样。
  4. 网页:

    package de.scrum_master.stackoverflow
    
    import geb.Page
    import geb.navigator.Navigator
    
    import java.time.Month
    import java.time.format.TextStyle
    
    import static java.util.Calendar.*
    
    class DatePickerPage extends Page {
      static url = "https://material.angularjs.org/1.1.2/demo/datepicker"
      static at = { heading == "Datepicker" }
      static now = new GregorianCalendar()
    
      static content = {
        heading { $("h2 > span.md-breadcrumb-page.ng-binding").text() }
        datePickerButtons { $("md-datepicker > button") }
        datePickerInputFields { $(".md-datepicker-input") }
        activeDatePicker(required: false) { $(".md-datepicker-calendar-pane.md-pane-open") }
        selectedDate { activeDatePicker.$(".md-calendar-selected-date") }
        currentMonthLabel {
          activeDatePicker
            .$("td.md-calendar-month-label", text: "${getMonthShort(now)} ${now.get(YEAR)}")
        }
        selectedMonth(required: false) { $("td.md-calendar-selected-date") }
      }
    
      String getDatePickerValue(Navigator datePickerInputField) {
        datePickerInputField.singleElement().getAttribute("value")
      }
    
      Navigator getMonthLabel(Calendar calendar) {
        $(".md-calendar-month-label", text: "${calendar.get(YEAR)}").closest("tbody")
          .$("span", text: getMonthShort(calendar)).closest("td")
      }
    
      Navigator getDayOfMonthLabel(Calendar calendar) {
        activeDatePicker
          .$(".md-calendar-month-label", text: "${getMonthShort(calendar)} ${calendar.get(YEAR)}")
          .closest("tbody")
          .$("span", text: "${calendar.get(DAY_OF_MONTH)}")
          .closest("td")
      }
    
      String getMonthShort(Calendar calendar) {
        Month
          .of(calendar.get(MONTH) + 1)
          .getDisplayName(TextStyle.FULL, new Locale("en"))
          .substring(0, 3)
      }
    }
    

    <强>测试

    package de.scrum_master.stackoverflow
    
    import geb.module.FormElement
    import geb.spock.GebReportingSpec
    import spock.lang.Unroll
    
    import static java.util.Calendar.*
    
    class DatePickerIT extends GebReportingSpec {
      def now = new GregorianCalendar()
      def xmas = new GregorianCalendar(now.get(YEAR), 12 - 1, 25)
    
      @Unroll
      def "Get selected date from Angular date label"() {
        when: "a date picker on the Angular demo page is chosen"
        DatePickerPage page = to DatePickerPage
        def datePickerInputField = page.datePickerInputFields[datePickerIndex]
    
        then: "that date picker instance is (in-)active as expected"
        datePickerInputField.module(FormElement).enabled == isEnabled
    
        when: "the active date is read from the date picker's text input field"
        String activeDateString = page.getDatePickerValue(datePickerInputField)
        String todayString = "${now.get(MONTH) + 1}/${now.get(DAY_OF_MONTH)}/${now.get(YEAR)}"
    
        then: "it is today"
        todayString == activeDateString
    
        where:
        datePickerIndex << [0, 1, 2, 3, 4, 5, 6, 7, 8]
        isEnabled << [true, false, true, true, true, true, true, true, true]
      }
    
      @Unroll
      def "Get selected date from opened Angular date picker"() {
        when: "a date picker on the Angular demo page is chosen"
        DatePickerPage page = to DatePickerPage
        def datePickerButton = page.datePickerButtons[datePickerIndex]
    
        then: "that date picker instance is active (not greyed out)"
        datePickerButton.module(FormElement).enabled
    
        when: "the calendar button for the date picker is clicked"
        datePickerButton.click()
    
        then: "the date picker pop-up opens, displaying the current month"
        waitFor 3, { page.activeDatePicker.displayed }
    
        when: "the active date's timestamp is read from the highlighted day in the calendar"
        def selectedDateMillis = page.selectedDate.attr("data-timestamp") as long
        def sinceMidnightMillis = now.getTimeInMillis() - selectedDateMillis
    
        then: "it is today"
        sinceMidnightMillis >= 0
        sinceMidnightMillis < 24 * 60 * 60 * 1000
    
        where:
        datePickerIndex << [0, 2, 4, 5, 6, 7, 8]
      }
    
      def "Set date in Angular date picker"() {
        when: "the first date picker's calendar button on the Angular demo page is clicked"
        DatePickerPage page = to DatePickerPage
        page.datePickerButtons[0].click()
    
        then: "the date picker pop-up opens, displaying the current month"
        waitFor 3, { page.activeDatePicker.displayed }
    
        when: "the current month label is clicked"
        page.currentMonthLabel.click()
    
        then: "the month selection page opens"
        waitFor 3, { page.selectedMonth.displayed }
        page.selectedMonth.text() == page.getMonthShort(now)
    
        when: "December for the current year is selected"
        page.getMonthLabel(xmas).click()
    
        then: "the month selection page closes again"
        waitFor 3, { !page.selectedMonth.displayed }
    
        when: "Xmas Day (25) is selected on the month calendar"
        page.getDayOfMonthLabel(xmas).click()
    
        then: "the date picker pop-up closes again"
        waitFor 3, { !page.activeDatePicker.displayed }
    
        when: "the active date is read from the date picker's text input field"
        String activeDateString = page.getDatePickerValue(page.datePickerInputFields[0])
        String xmasDayString = "${xmas.get(MONTH) + 1}/${xmas.get(DAY_OF_MONTH)}/${xmas.get(YEAR)}"
    
        then: "it is Xmas Day of the current year"
        xmasDayString == activeDateString
      }
    
    }
    

    这种方法的优点显而易见:您只能以用户/可能做的方式与页面交互,从而避免以用户不可能的方式操作页面(这会导致测试结果不佳)

    更新:我将代码重构为使用页面对象。