2017-01-18 8 views
2

Я хочу установить значение для datepicker, он имеет атрибут 'readonly'. Я попытался removeAttr() удалить атрибут, но получил ошибку вроде этого:Geb - Как удалить атрибут в Geb

Пойманные: groovy.lang.MissingMethodException: Нет подпись методы: geb.navigator.NonEmptyNavigator.removeAttr() применяется для типов аргументов: (ява .lang.String): [только для чтения]

Как удалить атрибут в 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"> 

мой ГЭБ код:

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

Спасибо всем

+0

Используйте следующий код для решения проблемы: js.exec ("document.getElementsByClassName ('ui-form-control ng-isolate-scope') [0] .removeAttribute ('readonly')") – Amy

+0

Если атрибут только для чтения и вы его изменяете, какой тест это? Вы проверяете то, что пользователь не может сделать на странице. Я думаю, это звучит довольно бессмысленно. Попытайтесь сосредоточиться на тестировании фактического поведения пользователя, а не на взломе страницы. Или вы используете Geb как средство автоматизации браузера и взлома страницы, а не как инструмент тестирования? В этом случае я понимаю вопрос, даже если это не то, для чего был изобретен Геб. – kriegaex

+0

kriegaex, на самом деле я не могу получить элементы (дату, месяц) datepicker (угловой) даже с помощью xpath, поэтому я хочу установить значение для datepicker напрямую. Но похоже, что он принимает только то значение, которое вы нажимаете. Я все еще не нахожу способ установить значение datepicker – Amy

ответ

0

Поскольку OP сказал, что это был AngularJS DatePicker, и я никогда не имел никаких контактов с Угловое, сам не будучи передний конец парень, я хотел бы узнать что-то, и теперь я разделяю его с вами, что бы это ни стоило.

Это тест Geb, который не использует никаких JS, но собирает информацию от Angular datepicker и взаимодействует с ним с помощью Geb или Selenium. Тест показывает, как

  1. получить выбранную дату из текстового поля Datepicker с помощью myNavigator.singleElement().getAttribute("value") (также работает для неактивных элементов управления),
  2. получить выбранную дату, открыв DatePicker и поиск выделенных дат в календарь (работает только для активных элементов управления, конечно),
  3. довольно утомительно взаимодействовать с DatePicker, выбрав Xmas день текущего года (декабрь-25) по
    • открытия DatePicker,
    • нажатия на текущем месяце для того, чтобы открыть месяц селектора года
    • щелкающих декабря, фактически закрыв селектор месяца снова
    • щелкать на 25-е дня, эффективно снова закрывая DatePicker,
    • наконец проверки, является ли правильная дата была установлена ​​путем чтения текстовой метки, как в примере # 1.

Страница:

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 
    } 

} 

Преимущество такого подхода очевидна: Вы только взаимодействовать со страницей в пути пользователя будет/может также делать, тем самым избегая манипулирования страницей способом, недоступным для пользователя (whi ch приведет к плохим испытаниям).

Обновление: Я переработал код в использовании объекта страницы.

+0

Обновление: я переработал код в использовании объекта страницы. – kriegaex

+0

Большое спасибо за вашу помощь! Ваш сценарий чрезвычайно помогает мне исправить мои проблемы. Теперь я взаимодействую со страницей, как это делают пользователи, вместо редактирования элементов – Amy

1

WebDriver и, таким образом, Геб не позволяют изменять DOM напрямую.

Вам необходимо будет использовать javascript через the js object, чтобы сделать то, что будет еще проще, если ваша страница загружена в jQuery благодаря Geb's jQuery integration.

+0

Спасибо за ваш ответ, если моя страница не загружена JQuery, как я могу удалить readonly или отправить значение для элемента? – Amy

+0

Я бы использовал javascript ['Element.removeAttribute()'] (https://developer.mozilla.org/en-US/docs/Web/API/Element/removeAttribute). – erdi

+0

Спасибо за вашу помощь, я решил проблему, см. Мой ответ ниже. – Amy

0

Используйте следующий код, чтобы решить эту проблему:

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

 Смежные вопросы

  • Нет связанных вопросов^_^